@@ -484,10 +484,27 @@ static void generic_glut_Close_handler(void)
484
484
DO_perl_call_sv (handler , G_DISCARD );
485
485
}
486
486
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
+
487
496
/* Callback for glutTimerFunc */
488
497
static void generic_glut_timer_handler (int value )
489
498
{
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
+
491
508
SV * handler ;
492
509
int i ;
493
510
dSP ;
@@ -1081,7 +1098,24 @@ glutTimerFunc(msecs, handler=0, ...)
1081
1098
1082
1099
PackCallbackST (handler_data , 1 );
1083
1100
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 );
1085
1119
}
1086
1120
ENSURE_callback_thread ;}
1087
1121
0 commit comments