functions.php
changeset 75 2f39cb7f54c4
parent 74 7719085707d8
--- a/functions.php	Fri Jun 12 11:57:08 2009 -0400
+++ b/functions.php	Fri Jun 12 13:47:12 2009 -0400
@@ -140,33 +140,56 @@
 
 $playlist_last_md5 = '';
 
-function rebuild_playlist()
+function rebuild_playlist($force = false, $from_ipc = false)
 {
   // import what we need
   global $playlist, $amarok_home;
   // sync and load the playlist file
-  $playlist_file = dcop_action('playlist', 'saveCurrentPlaylist');
+  // if we're coming from IPC, don't call DCOP, just load the existing file
+  // this prevents the file from being generated 20 times and thus sometimes
+  // causing simplexml to read a half-written file
+  if ( !$from_ipc )
+  {
+    $playlist_file = dcop_action('playlist', 'saveCurrentPlaylist');
+  }
+  else
+  {
+    $playlist_file = $from_ipc;
+  }
   // do we have amarok's home?
   if ( !$amarok_home )
     $amarok_home = dirname($playlist_file);
   // check MD5 - if it's not changed, exit to save CPU cycles
   global $playlist_last_md5;
   $effective_md5 = md5_playlist_file($playlist_file);
-  if ( $playlist_last_md5 == $effective_md5 )
+  if ( $playlist_last_md5 == $effective_md5 && !$force )
   {
     return true;
   }
   status('Rebuilding playlist cache');
   $playlist_last_md5 = $effective_md5;
-  // start XML parser
-  try
+  $originalplaylist = $playlist_file;
+  $xml = false;
+  $unlinkplaylist = false;
+  while ( !$xml )
   {
-    $xml = simplexml_load_file($playlist_file);
+    // start XML parser
+    try
+    {
+      $xml = @simplexml_load_file($playlist_file);
+      if ( $xml )
+        break;
+      
+      // if we can't load it, just wait - another process might have it loaded
+      warning('Could not load playlist file; maybe another Greyhound thread has it loaded? Waiting half a second.');
+      usleep(500000);
+    }
+    catch ( Exception $e )
+    {
+      burnout("Caught exception trying to load playlist file:\n$e");
+    }
   }
-  catch ( Exception $e )
-  {
-    burnout("Caught exception trying to load playlist file:\n$e");
-  }
+  
   $attribs = $xml->attributes();
   if ( @$attribs['product'] != 'Amarok' )
   {
@@ -186,11 +209,33 @@
       );
     $playlist[] = $item;
   }
-  // if we're a child process, signal the parent to update
-  if ( defined('HTTPD_WS_CHILD') )
+  if ( $unlinkplaylist )
+  {
+    unlink($playlist_file);
+  }
+  // tell all other worker threads to reload the playlist as well
+  global $httpd;
+  if ( is_object($httpd) && !$from_ipc )
   {
-    global $httpd;
-    posix_kill($httpd->parent_pid, SIGHUP);
+    $httpd->threader->ipc_send(array(
+        'action' => 'reloadplaylist',
+        'propagate' => true,
+        'playlist_file' => $playlist_file
+      ));
+  }
+}
+
+function rebuild_playlist_ipc($command, $threader)
+{
+  status('IPC playlist rebuild received');
+  if ( isset($command['playlist']) )
+  {
+    status('IPC playlist rebuild: using playlist sent in IPC packet; length: ' . strlen($command['playlist']));
+    $GLOBALS['playlist'] = $command['playlist'];
+  }
+  else
+  {
+    rebuild_playlist(true, $command['playlist_file']);
   }
 }