You are here

function ad_cache_file_get_lock in Advertisement 5.2

Same name and namespace in other branches
  1. 5 cache/file/ad_cache_file.inc \ad_cache_file_get_lock()
  2. 6.3 cache/file/ad_cache_file.inc \ad_cache_file_get_lock()
  3. 6 cache/file/ad_cache_file.inc \ad_cache_file_get_lock()
  4. 6.2 cache/file/ad_cache_file.inc \ad_cache_file_get_lock()
  5. 7 cache/file/ad_cache_file.inc \ad_cache_file_get_lock()

Try and obtain a lock on one of the available cache files. If we already have a lock, simply return the filename.

3 calls to ad_cache_file_get_lock()
ad_cache_file_close in cache/file/ad_cache_file.inc
Close the cache file and write updated cache to disk.
ad_cache_file_open in cache/file/ad_cache_file.inc
Initialization function. Loads cache from file into memory.
external.inc in external/external.inc
1 string reference to 'ad_cache_file_get_lock'
external.inc in external/external.inc

File

cache/file/ad_cache_file.inc, line 249
A plug in for the ad.module, providing a file cache mechanism for improved performance when displaying ads.

Code

function ad_cache_file_get_lock() {
  static $lock = FALSE;
  static $cache_file = '';
  if ($lock) {
    _debug_echo('File cache: already have lock.');
    return $cache_file;
  }

  // We'll loop through all possible cache files until we obtain an
  // exclusive lock.
  for ($i = 1; $i <= adserve_variable('files'); $i++) {

    // Prefix the filename with a '.' to hide it on Unix systems.
    $cache_file = adserve_variable('root_dir') . '/' . adserve_variable('path') . '/.' . $i . '.ad.cache';
    if (adserve_variable('debug')) {
      echo "Trying cache_file '{$cache_file}'.<br />\n";
    }
    if (!($fd = @fopen($cache_file, 'r+'))) {
      if (adserve_variable('debug')) {
        echo "Failed to open cache_file '{$cache_file}'.<br />\n";
      }

      // We failed to open the cache file, try the next one.
      continue;
    }
    if ($i < adserve_variable('files')) {

      // This isn't the last available cache file so we'll use a
      // non-blocking lock for best performance.  If we fail to lock this
      // cache file, we'll quickly move on to the next until we find an
      // available one.
      if (!flock($fd, LOCK_EX | LOCK_NB)) {
        if (adserve_variable('debug')) {
          echo "Failed to obtain non-blocking lock.<br />\n";
        }

        // We failed to obtain an exclusive lock, close the file and try the
        // next one.
        @fclose($fd);
        continue;
      }
      if (adserve_variable('debug')) {
        echo "Obtained lock.<br />\n";
        $stat = fstat($fd);
        echo 'File size: ' . $stat['size'] . '<br />';
      }
      $lock = TRUE;
      break;
    }
    else {

      // This is the last available cache file, we'll use a blocking lock
      // as we have to wait until we have exclusive write permissions.
      if (!flock($fd, LOCK_EX)) {
        if (adserve_variable('debug')) {
          echo "Failed to obtain blocking lock.<br />\n";
        }

        // A blocking exclusive lock shouldn't ever fail, so something has
        // gone very wrong.  Perhaps the file was deleted out from under us?
        @fclose($fd);
        continue;
      }
      if (adserve_variable('debug')) {
        echo "Obtained lock on final cache file.<br />\n";
      }
      $lock = TRUE;
      break;
    }
  }
  if ($lock) {
    adserve_variable('fd', $fd);
    return $cache_file;
  }
  else {
    return NULL;
  }
}