== modified file 'includes/common.inc' --- includes/common.inc 2010-08-18 00:44:52 +0000 +++ includes/common.inc 2010-08-19 22:05:48 +0000 @@ -3210,42 +3187,51 @@ function drupal_build_css_cache($css) { $uri = $map[$key]; } - if (empty($uri) || !file_exists($uri)) { - // Build aggregate CSS file. - foreach ($css as $stylesheet) { - // Only 'file' stylesheets can be aggregated. - if ($stylesheet['type'] == 'file') { - $contents = drupal_load_stylesheet($stylesheet['data'], TRUE); - // Return the path to where this CSS file originated from. - $base = base_path() . dirname($stylesheet['data']) . '/'; - _drupal_build_css_path(NULL, $base); - // Prefix all paths within this CSS file, ignoring external and absolute paths. - $data .= preg_replace_callback('/url\(\s*[\'"]?(?![a-z]+:|\/+)([^\'")]+)[\'"]?\s*\)/i', '_drupal_build_css_path', $contents); + $lock_acquire_attempts = 0; + do { + if (empty($uri) || !file_exists($uri)) { + if ($lock_acquired = lock_acquire($key)) { + // Build aggregate CSS file. + foreach ($css as $stylesheet) { + // Only 'file' stylesheets can be aggregated. + if ($stylesheet['type'] == 'file') { + $contents = drupal_load_stylesheet($stylesheet['data'], TRUE); + // Return the path to where this CSS file originated from. + $base = base_path() . dirname($stylesheet['data']) . '/'; + _drupal_build_css_path(NULL, $base); + // Prefix all paths within this CSS file, ignoring external and absolute paths. + $data .= preg_replace_callback('/url\([\'"]?(?![a-z]+:|\/+)([^\'")]+)[\'"]?\)/i', '_drupal_build_css_path', $contents); + } + } + + // Per the W3C specification at http://www.w3.org/TR/REC-CSS2/cascade.html#at-import, + // @import rules must proceed any other style, so we move those to the top. + $regexp = '/@import[^;]+;/i'; + preg_match_all($regexp, $data, $matches); + $data = preg_replace($regexp, '', $data); + $data = implode('', $matches[0]) . $data; + + // Prefix filename to prevent blocking by firewalls which reject files + // starting with "ad*". + $filename = 'css_' . drupal_hash_base64($data) . '.css'; + // Create the css/ within the files folder. + $csspath = 'public://css'; + $uri = $csspath . '/' . $filename; + // Create the CSS file. + file_prepare_directory($csspath, FILE_CREATE_DIRECTORY); + if (!file_exists($uri) && !file_unmanaged_save_data($data, $uri, FILE_EXISTS_REPLACE)) { + return FALSE; + } + // Save the updated map. + $map[$key] = $uri; + variable_set('drupal_css_cache_files', $map); + } + else { + lock_wait(); } } - - // Per the W3C specification at http://www.w3.org/TR/REC-CSS2/cascade.html#at-import, - // @import rules must proceed any other style, so we move those to the top. - $regexp = '/@import[^;]+;/i'; - preg_match_all($regexp, $data, $matches); - $data = preg_replace($regexp, '', $data); - $data = implode('', $matches[0]) . $data; - - // Prefix filename to prevent blocking by firewalls which reject files - // starting with "ad*". - $filename = 'css_' . drupal_hash_base64($data) . '.css'; - // Create the css/ within the files folder. - $csspath = 'public://css'; - $uri = $csspath . '/' . $filename; - // Create the CSS file. - file_prepare_directory($csspath, FILE_CREATE_DIRECTORY); - if (!file_exists($uri) && !file_unmanaged_save_data($data, $uri, FILE_EXISTS_REPLACE)) { - return FALSE; - } - // Save the updated map. - $map[$key] = $uri; - variable_set('drupal_css_cache_files', $map); } + while (!file_exists($uri) && $lock_acquired === FALSE && ++$lock_acquire_attempts < 5); return $uri; } @@ -3599,25 +3585,6 @@ function drupal_region_class($region) { * Calling drupal_static_reset('drupal_add_js') will clear all JavaScript added * so far. * - * If JavaScript aggregation is enabled, all JavaScript files added with - * $options['preprocess'] set to TRUE will be merged into one aggregate file. - * Preprocessed inline JavaScript will not be aggregated into this single file. - * Externally hosted JavaScripts are never aggregated. - * - * The reason for aggregating the files is outlined quite thoroughly here: - * http://www.die.net/musings/page_load_time/ "Load fewer external objects. Due - * to request overhead, one bigger file just loads faster than two smaller ones - * half its size." - * - * $options['preprocess'] should be only set to TRUE when a file is required for - * all typical visitors and most pages of a site. It is critical that all - * preprocessed files are added unconditionally on every page, even if the - * files are not needed on a page. This is normally done by calling - * drupal_add_css() in a hook_init() implementation. - * - * Non-preprocessed files should only be added to the page when they are - * actually needed. - * * @param $data * (optional) If given, the value depends on the $options parameter: * - 'file': Path to the file relative to base_path(). @@ -3659,8 +3626,9 @@ function drupal_region_class($region) { * - cache: If set to FALSE, the JavaScript file is loaded anew on every page * call; in other words, it is not cached. Used only when 'type' references * a JavaScript file. Defaults to TRUE. - * - preprocess: If TRUE and JavaScript aggregation is enabled, the script - * file will be aggregated. Defaults to FALSE. + * - preprocess: Aggregate the JavaScript if the JavaScript optimization + * setting has been toggled in admin/config/development/performance. Note + * that JavaScript of type 'external' is not aggregated. Defaults to TRUE. * * @return * The current array of JavaScript files, settings, and in-line code, @@ -3753,7 +3721,7 @@ function drupal_js_defaults($data = NULL 'scope' => 'header', 'cache' => TRUE, 'defer' => FALSE, - 'preprocess' => FALSE, + 'preprocess' => TRUE, 'version' => NULL, 'data' => $data, ); @@ -4421,28 +4389,38 @@ function drupal_build_js_cache($files) { $uri = $map[$key]; } if (empty($uri) || !file_exists($uri)) { - // Build aggregate JS file. - foreach ($files as $path => $info) { - if ($info['preprocess']) { - // Append a ';' and a newline after each JS file to prevent them from running together. - $contents .= file_get_contents($path) . ";\n"; - } - } - // Prefix filename to prevent blocking by firewalls which reject files - // starting with "ad*". - $filename = 'js_' . drupal_hash_base64($contents) . '.js'; - // Create the js/ within the files folder. - $jspath = 'public://js'; - $uri = $jspath . '/' . $filename; - // Create the JS file. - file_prepare_directory($jspath, FILE_CREATE_DIRECTORY); - if (!file_unmanaged_save_data($contents, $uri, FILE_EXISTS_REPLACE)) { - return FALSE; + $lock_acquire_attempts = 0; + do { + if (empty($uri) || !file_exists($uri)) { + if ($lock_acquired = lock_acquire($key)) { + // Build aggregate JS file. + foreach ($files as $path => $info) { + if ($info['preprocess']) { + // Append a ';' and a newline after each JS file to prevent them from running together. + $contents .= file_get_contents($path) . ";\n"; + } + } + // Prefix filename to prevent blocking by firewalls which reject files + // starting with "ad*". + $filename = 'js_' . drupal_hash_base64($contents) . '.js'; + // Create the js/ within the files folder. + $jspath = 'public://js'; + $uri = $jspath . '/' . $filename; + // Create the JS file. + file_prepare_directory($jspath, FILE_CREATE_DIRECTORY); + if (!file_unmanaged_save_data($contents, $uri, FILE_EXISTS_REPLACE)) { + return FALSE; + } + $map[$key] = $uri; + variable_set('drupal_js_cache_files', $map); + lock_release($key); + } + else { + lock_wait(); + } } - $map[$key] = $uri; - variable_set('drupal_js_cache_files', $map); } + while (!file_exists($uri) && $lock_acquired === FALSE && ++$lock_acquire_attempts < 5); return $uri; }