@@ -484,10 +484,27 @@ static void generic_glut_Close_handler(void)
484484 DO_perl_call_sv (handler , G_DISCARD );
485485}
486486
487+ /* glut_timer_handlers is an allocation buffer.
488+ All unused elements are SVivs forming a linked-list,
489+ starting at glut_timer_handlers_next_free.
490+ The end of the list is marked by a -1.
491+ If no element is free when one is needed, the buffer will grow.
492+ */
493+ static AV * glut_timer_handlers = 0 ;
494+ static int glut_timer_handlers_next_free = -1 ;
495+
487496/* Callback for glutTimerFunc */
488497static void generic_glut_timer_handler (int value )
489498{
490- AV * handler_data = (AV * )value ;
499+ if (!glut_timer_handlers )
500+ croak ("Timer handler called, but no timers have ever been set up" );
501+ SV * * h = av_fetch (glut_timer_handlers ,value ,FALSE);
502+ if (!h || !SvOK (* h ) || !SvROK (* h ))
503+ croak ("Timer handler called for unregistered timer" );
504+ AV * handler_data = (AV * )SvRV (* h );
505+ sv_setiv (* h ,glut_timer_handlers_next_free );
506+ glut_timer_handlers_next_free = value ;
507+
491508 SV * handler ;
492509 int i ;
493510 dSP ;
@@ -1081,7 +1098,24 @@ glutTimerFunc(msecs, handler=0, ...)
10811098
10821099 PackCallbackST (handler_data , 1 );
10831100
1084- glutTimerFunc (msecs , generic_glut_timer_handler , (int )handler_data );
1101+ SV * handler_data_sv = newRV_inc ((SV * )handler_data );
1102+
1103+ if (!glut_timer_handlers )
1104+ glut_timer_handlers = newAV ();
1105+
1106+ int handler_id = glut_timer_handlers_next_free ;
1107+ if (handler_id == -1 ) {
1108+ handler_id = ((int ) av_len (glut_timer_handlers ))+ 1 ;
1109+ if (handler_id < 0 )
1110+ croak ("Limit of concurrent timers reached (MAX_INT)" );
1111+ av_push (glut_timer_handlers , handler_data_sv );
1112+ } else {
1113+ SV * * entry = av_fetch (glut_timer_handlers ,handler_id ,FALSE);
1114+ glut_timer_handlers_next_free = SvIV (* entry );
1115+ sv_setsv (* entry ,sv_2mortal (handler_data_sv ));
1116+ }
1117+
1118+ glutTimerFunc (msecs , generic_glut_timer_handler , handler_id );
10851119 }
10861120 ENSURE_callback_thread ;}
10871121
0 commit comments