@@ -612,8 +612,10 @@ set_sqlite_error(sqlite3_context *context, const char *msg)
612612 else {
613613 sqlite3_result_error (context , msg , -1 );
614614 }
615- pysqlite_state * state = pysqlite_get_state (NULL );
616- if (state -> enable_callback_tracebacks ) {
615+ callback_context * ctx = (callback_context * )sqlite3_user_data (context );
616+ assert (ctx != NULL );
617+ assert (ctx -> state != NULL );
618+ if (ctx -> state -> enable_callback_tracebacks ) {
617619 PyErr_Print ();
618620 }
619621 else {
@@ -625,19 +627,18 @@ static void
625627_pysqlite_func_callback (sqlite3_context * context , int argc , sqlite3_value * * argv )
626628{
627629 PyObject * args ;
628- PyObject * py_func ;
629630 PyObject * py_retval = NULL ;
630631 int ok ;
631632
632633 PyGILState_STATE threadstate ;
633634
634635 threadstate = PyGILState_Ensure ();
635636
636- py_func = (PyObject * )sqlite3_user_data (context );
637-
638637 args = _pysqlite_build_py_params (context , argc , argv );
639638 if (args ) {
640- py_retval = PyObject_CallObject (py_func , args );
639+ callback_context * ctx = (callback_context * )sqlite3_user_data (context );
640+ assert (ctx != NULL );
641+ py_retval = PyObject_CallObject (ctx -> callable , args );
641642 Py_DECREF (args );
642643 }
643644
@@ -657,20 +658,19 @@ static void _pysqlite_step_callback(sqlite3_context *context, int argc, sqlite3_
657658{
658659 PyObject * args ;
659660 PyObject * function_result = NULL ;
660- PyObject * aggregate_class ;
661661 PyObject * * aggregate_instance ;
662662 PyObject * stepmethod = NULL ;
663663
664664 PyGILState_STATE threadstate ;
665665
666666 threadstate = PyGILState_Ensure ();
667667
668- aggregate_class = (PyObject * )sqlite3_user_data (context );
669-
670668 aggregate_instance = (PyObject * * )sqlite3_aggregate_context (context , sizeof (PyObject * ));
671669
672670 if (* aggregate_instance == NULL ) {
673- * aggregate_instance = _PyObject_CallNoArg (aggregate_class );
671+ callback_context * ctx = (callback_context * )sqlite3_user_data (context );
672+ assert (ctx != NULL );
673+ * aggregate_instance = _PyObject_CallNoArg (ctx -> callable );
674674 if (!* aggregate_instance ) {
675675 set_sqlite_error (context ,
676676 "user-defined aggregate's '__init__' method raised error" );
@@ -784,14 +784,35 @@ static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self)
784784 Py_SETREF (self -> cursors , new_list );
785785}
786786
787- static void _destructor (void * args )
787+ static callback_context *
788+ create_callback_context (pysqlite_state * state , PyObject * callable )
788789{
789- // This function may be called without the GIL held, so we need to ensure
790- // that we destroy 'args' with the GIL
791- PyGILState_STATE gstate ;
792- gstate = PyGILState_Ensure ();
793- Py_DECREF ((PyObject * )args );
790+ PyGILState_STATE gstate = PyGILState_Ensure ();
791+ callback_context * ctx = PyMem_Malloc (sizeof (callback_context ));
792+ if (ctx != NULL ) {
793+ ctx -> callable = Py_NewRef (callable );
794+ ctx -> state = state ;
795+ }
794796 PyGILState_Release (gstate );
797+ return ctx ;
798+ }
799+
800+ static void
801+ free_callback_context (callback_context * ctx )
802+ {
803+ if (ctx != NULL ) {
804+ // This function may be called without the GIL held, so we need to
805+ // ensure that we destroy 'ctx' with the GIL held.
806+ PyGILState_STATE gstate = PyGILState_Ensure ();
807+ Py_DECREF (ctx -> callable );
808+ PyMem_Free (ctx );
809+ PyGILState_Release (gstate );
810+ }
811+ }
812+
813+ static void _destructor (void * args )
814+ {
815+ free_callback_context ((callback_context * )args );
795816}
796817
797818/*[clinic input]
@@ -833,11 +854,11 @@ pysqlite_connection_create_function_impl(pysqlite_Connection *self,
833854 flags |= SQLITE_DETERMINISTIC ;
834855#endif
835856 }
836- rc = sqlite3_create_function_v2 (self -> db ,
837- name ,
838- narg ,
839- flags ,
840- ( void * ) Py_NewRef ( func ) ,
857+ callback_context * ctx = create_callback_context (self -> state , func );
858+ if ( ctx == NULL ) {
859+ return NULL ;
860+ }
861+ rc = sqlite3_create_function_v2 ( self -> db , name , narg , flags , ctx ,
841862 _pysqlite_func_callback ,
842863 NULL ,
843864 NULL ,
@@ -873,11 +894,12 @@ pysqlite_connection_create_aggregate_impl(pysqlite_Connection *self,
873894 return NULL ;
874895 }
875896
876- rc = sqlite3_create_function_v2 (self -> db ,
877- name ,
878- n_arg ,
879- SQLITE_UTF8 ,
880- (void * )Py_NewRef (aggregate_class ),
897+ callback_context * ctx = create_callback_context (self -> state ,
898+ aggregate_class );
899+ if (ctx == NULL ) {
900+ return NULL ;
901+ }
902+ rc = sqlite3_create_function_v2 (self -> db , name , n_arg , SQLITE_UTF8 , ctx ,
881903 0 ,
882904 & _pysqlite_step_callback ,
883905 & _pysqlite_final_callback ,
@@ -1439,7 +1461,6 @@ pysqlite_collation_callback(
14391461 int text1_length , const void * text1_data ,
14401462 int text2_length , const void * text2_data )
14411463{
1442- PyObject * callback = (PyObject * )context ;
14431464 PyObject * string1 = 0 ;
14441465 PyObject * string2 = 0 ;
14451466 PyGILState_STATE gilstate ;
@@ -1459,8 +1480,10 @@ pysqlite_collation_callback(
14591480 goto finally ; /* failed to allocate strings */
14601481 }
14611482
1483+ callback_context * ctx = (callback_context * )context ;
1484+ assert (ctx != NULL );
14621485 PyObject * args [] = { string1 , string2 }; // Borrowed refs.
1463- retval = PyObject_Vectorcall (callback , args , 2 , NULL );
1486+ retval = PyObject_Vectorcall (ctx -> callable , args , 2 , NULL );
14641487 if (retval == NULL ) {
14651488 /* execution failed */
14661489 goto finally ;
@@ -1690,6 +1713,7 @@ pysqlite_connection_create_collation_impl(pysqlite_Connection *self,
16901713 return NULL ;
16911714 }
16921715
1716+ callback_context * ctx = NULL ;
16931717 int rc ;
16941718 int flags = SQLITE_UTF8 ;
16951719 if (callable == Py_None ) {
@@ -1701,8 +1725,11 @@ pysqlite_connection_create_collation_impl(pysqlite_Connection *self,
17011725 PyErr_SetString (PyExc_TypeError , "parameter must be callable" );
17021726 return NULL ;
17031727 }
1704- rc = sqlite3_create_collation_v2 (self -> db , name , flags ,
1705- Py_NewRef (callable ),
1728+ ctx = create_callback_context (self -> state , callable );
1729+ if (ctx == NULL ) {
1730+ return NULL ;
1731+ }
1732+ rc = sqlite3_create_collation_v2 (self -> db , name , flags , ctx ,
17061733 & pysqlite_collation_callback ,
17071734 & _destructor );
17081735 }
@@ -1713,7 +1740,7 @@ pysqlite_connection_create_collation_impl(pysqlite_Connection *self,
17131740 * the context before returning.
17141741 */
17151742 if (callable != Py_None ) {
1716- Py_DECREF ( callable );
1743+ free_callback_context ( ctx );
17171744 }
17181745 _pysqlite_seterror (self -> state , self -> db );
17191746 return NULL ;
0 commit comments