functions.php
changeset 75 2f39cb7f54c4
parent 74 7719085707d8
equal deleted inserted replaced
74:7719085707d8 75:2f39cb7f54c4
   138  * Rebuilds the copy of the playlist in RAM
   138  * Rebuilds the copy of the playlist in RAM
   139  */
   139  */
   140 
   140 
   141 $playlist_last_md5 = '';
   141 $playlist_last_md5 = '';
   142 
   142 
   143 function rebuild_playlist()
   143 function rebuild_playlist($force = false, $from_ipc = false)
   144 {
   144 {
   145   // import what we need
   145   // import what we need
   146   global $playlist, $amarok_home;
   146   global $playlist, $amarok_home;
   147   // sync and load the playlist file
   147   // sync and load the playlist file
   148   $playlist_file = dcop_action('playlist', 'saveCurrentPlaylist');
   148   // if we're coming from IPC, don't call DCOP, just load the existing file
       
   149   // this prevents the file from being generated 20 times and thus sometimes
       
   150   // causing simplexml to read a half-written file
       
   151   if ( !$from_ipc )
       
   152   {
       
   153     $playlist_file = dcop_action('playlist', 'saveCurrentPlaylist');
       
   154   }
       
   155   else
       
   156   {
       
   157     $playlist_file = $from_ipc;
       
   158   }
   149   // do we have amarok's home?
   159   // do we have amarok's home?
   150   if ( !$amarok_home )
   160   if ( !$amarok_home )
   151     $amarok_home = dirname($playlist_file);
   161     $amarok_home = dirname($playlist_file);
   152   // check MD5 - if it's not changed, exit to save CPU cycles
   162   // check MD5 - if it's not changed, exit to save CPU cycles
   153   global $playlist_last_md5;
   163   global $playlist_last_md5;
   154   $effective_md5 = md5_playlist_file($playlist_file);
   164   $effective_md5 = md5_playlist_file($playlist_file);
   155   if ( $playlist_last_md5 == $effective_md5 )
   165   if ( $playlist_last_md5 == $effective_md5 && !$force )
   156   {
   166   {
   157     return true;
   167     return true;
   158   }
   168   }
   159   status('Rebuilding playlist cache');
   169   status('Rebuilding playlist cache');
   160   $playlist_last_md5 = $effective_md5;
   170   $playlist_last_md5 = $effective_md5;
   161   // start XML parser
   171   $originalplaylist = $playlist_file;
   162   try
   172   $xml = false;
   163   {
   173   $unlinkplaylist = false;
   164     $xml = simplexml_load_file($playlist_file);
   174   while ( !$xml )
   165   }
   175   {
   166   catch ( Exception $e )
   176     // start XML parser
   167   {
   177     try
   168     burnout("Caught exception trying to load playlist file:\n$e");
   178     {
   169   }
   179       $xml = @simplexml_load_file($playlist_file);
       
   180       if ( $xml )
       
   181         break;
       
   182       
       
   183       // if we can't load it, just wait - another process might have it loaded
       
   184       warning('Could not load playlist file; maybe another Greyhound thread has it loaded? Waiting half a second.');
       
   185       usleep(500000);
       
   186     }
       
   187     catch ( Exception $e )
       
   188     {
       
   189       burnout("Caught exception trying to load playlist file:\n$e");
       
   190     }
       
   191   }
       
   192   
   170   $attribs = $xml->attributes();
   193   $attribs = $xml->attributes();
   171   if ( @$attribs['product'] != 'Amarok' )
   194   if ( @$attribs['product'] != 'Amarok' )
   172   {
   195   {
   173     burnout('Playlist is not in Amarok format');
   196     burnout('Playlist is not in Amarok format');
   174   }
   197   }
   184         'length' => seconds_to_str(intval($child->Length)),
   207         'length' => seconds_to_str(intval($child->Length)),
   185         'length_int' => intval($child->Length)
   208         'length_int' => intval($child->Length)
   186       );
   209       );
   187     $playlist[] = $item;
   210     $playlist[] = $item;
   188   }
   211   }
   189   // if we're a child process, signal the parent to update
   212   if ( $unlinkplaylist )
   190   if ( defined('HTTPD_WS_CHILD') )
   213   {
   191   {
   214     unlink($playlist_file);
   192     global $httpd;
   215   }
   193     posix_kill($httpd->parent_pid, SIGHUP);
   216   // tell all other worker threads to reload the playlist as well
       
   217   global $httpd;
       
   218   if ( is_object($httpd) && !$from_ipc )
       
   219   {
       
   220     $httpd->threader->ipc_send(array(
       
   221         'action' => 'reloadplaylist',
       
   222         'propagate' => true,
       
   223         'playlist_file' => $playlist_file
       
   224       ));
       
   225   }
       
   226 }
       
   227 
       
   228 function rebuild_playlist_ipc($command, $threader)
       
   229 {
       
   230   status('IPC playlist rebuild received');
       
   231   if ( isset($command['playlist']) )
       
   232   {
       
   233     status('IPC playlist rebuild: using playlist sent in IPC packet; length: ' . strlen($command['playlist']));
       
   234     $GLOBALS['playlist'] = $command['playlist'];
       
   235   }
       
   236   else
       
   237   {
       
   238     rebuild_playlist(true, $command['playlist_file']);
   194   }
   239   }
   195 }
   240 }
   196 
   241 
   197 /**
   242 /**
   198  * Builds the correct MD5 check for the specified playlist XML file. This is designed to base on the list of actual tracks, disregarding
   243  * Builds the correct MD5 check for the specified playlist XML file. This is designed to base on the list of actual tracks, disregarding