We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 1192

Summary: Restoring an app gets stuck in an infinite loop.
Product: SDL Reporter: Jeremy Jurksztowicz <jurksztowicz>
Component: videoAssignee: Sam Lantinga <slouken>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: blocker    
Priority: P2 CC: jurksztowicz
Version: HG 2.0   
Hardware: iPhone/iPod touch   
OS: iOS (All)   

Description Jeremy Jurksztowicz 2011-04-27 17:57:52 UTC
SDL_render_gles2.c, function [GLES2_CacheProgram]:

entry = rdata->program_cache.head; 
    while (entry) 
    {
        if (entry->vertex_shader == vertex && entry->fragment_shader == fragment) 
            break; 
        entry = entry->next;  // <-PROBLEM HERE
    }

The rdata->program_cache.head node's next and prev pointers point to itself, hence infinite loop.
Comment 1 Jeremy Jurksztowicz 2011-05-07 20:14:48 UTC
The linked list code in SDL_render_gles2.c is faulty. It's actually a circular linked list.
Comment 2 Jeremy Jurksztowicz 2011-05-07 20:54:59 UTC
This is a WORKAROUND, not a fix, as the linked list should be constructed properly.

Change:

    /* Check if we've already cached this program */
    entry = rdata->program_cache.head;
    while (entry)
    {
        if (entry->vertex_shader == vertex && entry->fragment_shader == fragment)
            break;
			
        entry = entry->next;
    }

To:

    /* Check if we've already cached this program */
    entry = rdata->program_cache.head;
    while (entry)
    {
        if (entry->vertex_shader == vertex && entry->fragment_shader == fragment)
            break;
			
		/* Quick 'n dirty hack! The linked list is not managed properly. */
		if(entry == rdata->program_cache.tail)
		{
			entry = 0;
			break;
		}
			
        entry = entry->next;
    }
Comment 3 Jeremy Jurksztowicz 2011-05-08 07:46:16 UTC
FAIL! Last workaround screws up cache hit rate. This one is works by relying on the node count being accurate to avoid the infinite loop.

numCaches = rdata->program_cache.count; 
   if(numCaches < 0) 
      return NULL; 
       
    while (entry && numCaches) 
    { 
        if (entry->vertex_shader == vertex && entry->fragment_shader == fragment) 
            break; 
                
        entry = entry->next; 
       
      if(--numCaches <= 0) 
      { 
         entry = 0; 
         break; 
      } 
    }
Comment 4 Sam Lantinga 2012-01-06 22:44:11 UTC
Hahah, yeah, I ran into this one myself and fixed it a couple months ago.  Can you take a look at the latest SDL snapshot and see if the fix looks good to you?
http://www.libsdl.org/tmp/SDL-1.3.zip