aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMeik Sievertsen <acydburn@phpbb.com>2009-03-19 17:01:59 +0000
committerMeik Sievertsen <acydburn@phpbb.com>2009-03-19 17:01:59 +0000
commite461162847b1ac9287870de680e8dbd17e9f2fc1 (patch)
treee93351f9856ea56167c7c40a5c765318184df5d9
parentbcabff8a1fe82452366b6f278782fd284effece4 (diff)
downloadforums-e461162847b1ac9287870de680e8dbd17e9f2fc1.tar
forums-e461162847b1ac9287870de680e8dbd17e9f2fc1.tar.gz
forums-e461162847b1ac9287870de680e8dbd17e9f2fc1.tar.bz2
forums-e461162847b1ac9287870de680e8dbd17e9f2fc1.tar.xz
forums-e461162847b1ac9287870de680e8dbd17e9f2fc1.zip
Fix race condition for updating post/topic/etc. counter. (reported by BartVB)
please do not try such fixes at home - the correct solution would be to create a second config table with integer columns. ;) git-svn-id: file:///svn/phpbb/branches/phpBB-3_0_0@9398 89ea8834-ac86-4346-8a33-228a782c2dd0
-rw-r--r--phpBB/docs/CHANGELOG.html1
-rw-r--r--phpBB/includes/acp/acp_attachments.php4
-rw-r--r--phpBB/includes/functions.php31
-rw-r--r--phpBB/includes/functions_admin.php8
-rw-r--r--phpBB/includes/functions_posting.php16
-rw-r--r--phpBB/includes/functions_privmsgs.php6
-rw-r--r--phpBB/includes/functions_user.php8
-rw-r--r--phpBB/includes/mcp/mcp_main.php4
-rw-r--r--phpBB/includes/mcp/mcp_queue.php4
-rw-r--r--phpBB/includes/mcp/mcp_topic.php2
10 files changed, 58 insertions, 26 deletions
diff --git a/phpBB/docs/CHANGELOG.html b/phpBB/docs/CHANGELOG.html
index 8475ac3246..52ebf5e5b6 100644
--- a/phpBB/docs/CHANGELOG.html
+++ b/phpBB/docs/CHANGELOG.html
@@ -125,6 +125,7 @@
<li>[Fix] Flash files do not display anymore after update to flash player 10 (Bug #41315)</li>
<li>[Fix] Use FQDN for SMTP EHLO/HELO command. (Bug #41025)</li>
<li>[Fix] Mass Email works again for users with empty jabber address but notification set to 'both'. (Bug #39755)</li>
+ <li>[Fix] Fix race condition for updating post/topic/etc. counter. (reported by BartVB)</li>
<li>[Change] Allow download of conflicting file for later reference in automatic updater</li>
<li>[Change] Default difference view is now 'inline' instead of 'side by side'</li>
<li>[Change] Added new option for merging differences to conflicting files in automatic updater</li>
diff --git a/phpBB/includes/acp/acp_attachments.php b/phpBB/includes/acp/acp_attachments.php
index 15e9e6ab62..ef20b48cec 100644
--- a/phpBB/includes/acp/acp_attachments.php
+++ b/phpBB/includes/acp/acp_attachments.php
@@ -1003,8 +1003,8 @@ class acp_attachments
if ($files_added)
{
- set_config('upload_dir_size', $config['upload_dir_size'] + $space_taken, true);
- set_config('num_files', $config['num_files'] + $files_added, true);
+ set_config_count('upload_dir_size', $space_taken, true);
+ set_config_count('num_files', $files_added, true);
}
}
}
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index 248a478145..30d3e50be8 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -165,6 +165,37 @@ function set_config($config_name, $config_value, $is_dynamic = false)
}
/**
+* Set dynamic config value with arithmetic operation.
+*/
+function set_config_count($config_name, $increment, $is_dynamic = false)
+{
+ global $db, $cache;
+
+ switch ($db->sql_layer)
+ {
+ case 'firebird':
+ $sql_update = 'CAST(CAST(config_value as integer) + ' . (int) $increment . ' as CHAR)';
+ break;
+
+ case 'postgres':
+ $sql_update = 'int4(config_value) + ' . (int) $increment;
+ break;
+
+ // MySQL, SQlite, mssql, mssql_odbc, oracle
+ default:
+ $sql_update = 'config_value + ' . (int) $increment;
+ break;
+ }
+
+ $db->sql_query('UPDATE ' . CONFIG_TABLE . ' SET config_value = ' . $sql_update . " WHERE config_name = '" . $db->sql_escape($config_name) . "'");
+
+ if (!$is_dynamic)
+ {
+ $cache->destroy('config');
+ }
+}
+
+/**
* Generates an alphanumeric random string of given length
*/
function gen_rand_string($num_chars = 8)
diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php
index 5da18d250c..549f854b78 100644
--- a/phpBB/includes/functions_admin.php
+++ b/phpBB/includes/functions_admin.php
@@ -619,7 +619,7 @@ function delete_topics($where_type, $where_ids, $auto_sync = true, $post_count_s
if ($approved_topics)
{
- set_config('num_topics', $config['num_topics'] - $approved_topics, true);
+ set_config_count('num_topics', $approved_topics * (-1), true);
}
return $return;
@@ -776,7 +776,7 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync =
if ($approved_posts)
{
- set_config('num_posts', $config['num_posts'] - $approved_posts, true);
+ set_config_count('num_posts', $approved_posts * (-1), true);
}
// We actually remove topics now to not be inconsistent (the delete_topics function calls this function too)
@@ -903,8 +903,8 @@ function delete_attachments($mode, $ids, $resync = true)
if ($space_removed || $files_removed)
{
- set_config('upload_dir_size', $config['upload_dir_size'] - $space_removed, true);
- set_config('num_files', $config['num_files'] - $files_removed, true);
+ set_config_count('upload_dir_size', $space_removed * (-1), true);
+ set_config_count('num_files', $files_removed * (-1), true);
}
// If we do not resync, we do not need to adjust any message, post, topic or user entries
diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php
index 8ec82d4f16..e44454b5ff 100644
--- a/phpBB/includes/functions_posting.php
+++ b/phpBB/includes/functions_posting.php
@@ -1849,8 +1849,8 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_topics = forum_topics - 1';
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts - ' . ($topic_row['topic_replies'] + 1);
- set_config('num_topics', $config['num_topics'] - 1, true);
- set_config('num_posts', $config['num_posts'] - ($topic_row['topic_replies'] + 1), true);
+ set_config_count('num_topics', -1, true);
+ set_config_count('num_posts', ($topic_row['topic_replies'] + 1) * (-1), true);
// Only decrement this post, since this is the one non-approved now
if ($auth->acl_get('f_postcount', $data['forum_id']))
@@ -1870,7 +1870,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
$sql_data[TOPICS_TABLE]['stat'][] = 'topic_replies = topic_replies - 1';
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts - 1';
- set_config('num_posts', $config['num_posts'] - 1, true);
+ set_config_count('num_posts', -1, true);
if ($auth->acl_get('f_postcount', $data['forum_id']))
{
@@ -2137,8 +2137,8 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
if ($space_taken && $files_added)
{
- set_config('upload_dir_size', $config['upload_dir_size'] + $space_taken, true);
- set_config('num_files', $config['num_files'] + $files_added, true);
+ set_config_count('upload_dir_size', $space_taken, true);
+ set_config_count('num_files', $files_added, true);
}
}
@@ -2371,13 +2371,13 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
{
if ($post_mode == 'post')
{
- set_config('num_topics', $config['num_topics'] + 1, true);
- set_config('num_posts', $config['num_posts'] + 1, true);
+ set_config_count('num_topics', 1, true);
+ set_config_count('num_posts', 1, true);
}
if ($post_mode == 'reply')
{
- set_config('num_posts', $config['num_posts'] + 1, true);
+ set_config_count('num_posts', 1, true);
}
}
diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php
index 4926cabf2c..0b02da054a 100644
--- a/phpBB/includes/functions_privmsgs.php
+++ b/phpBB/includes/functions_privmsgs.php
@@ -1350,7 +1350,7 @@ function submit_pm($mode, $subject, &$data, $put_in_outbox = true)
WHERE ' . $db->sql_in_set('ug.group_id', array_keys($data['address_list']['g'])) . '
AND ug.user_pending = 0
AND u.user_id = ug.user_id
- AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')' .
+ AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')' .
$sql_allow_pm;
$result = $db->sql_query($sql);
@@ -1571,8 +1571,8 @@ function submit_pm($mode, $subject, &$data, $put_in_outbox = true)
if ($space_taken && $files_added)
{
- set_config('upload_dir_size', $config['upload_dir_size'] + $space_taken, true);
- set_config('num_files', $config['num_files'] + $files_added, true);
+ set_config_count('upload_dir_size', $space_taken, true);
+ set_config_count('num_files', $files_added, true);
}
}
diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php
index 108e884abd..6a45011977 100644
--- a/phpBB/includes/functions_user.php
+++ b/phpBB/includes/functions_user.php
@@ -280,7 +280,7 @@ function user_add($user_row, $cp_data = false)
{
set_config('newest_user_id', $user_id, true);
set_config('newest_username', $user_row['username'], true);
- set_config('num_users', $config['num_users'] + 1, true);
+ set_config_count('num_users', 1, true);
$sql = 'SELECT group_colour
FROM ' . GROUPS_TABLE . '
@@ -579,7 +579,7 @@ function user_delete($mode, $user_id, $post_username = false)
// Decrement number of users if this user is active
if ($user_row['user_type'] != USER_INACTIVE && $user_row['user_type'] != USER_IGNORE)
{
- set_config('num_users', $config['num_users'] - 1, true);
+ set_config_count('num_users', -1, true);
}
return false;
@@ -660,12 +660,12 @@ function user_active_flip($mode, $user_id_ary, $reason = INACTIVE_MANUAL)
if ($deactivated)
{
- set_config('num_users', $config['num_users'] - $deactivated, true);
+ set_config_count('num_users', $deactivated * (-1), true);
}
if ($activated)
{
- set_config('num_users', $config['num_users'] + $activated, true);
+ set_config_count('num_users', $activated, true);
}
// Update latest username
diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php
index 2cde1d4076..0e0bfe7bf5 100644
--- a/phpBB/includes/mcp/mcp_main.php
+++ b/phpBB/includes/mcp/mcp_main.php
@@ -1194,8 +1194,8 @@ function mcp_fork_topic($topic_ids)
}
sync('forum', 'forum_id', $to_forum_id);
- set_config('num_topics', $config['num_topics'] + sizeof($new_topic_id_list), true);
- set_config('num_posts', $config['num_posts'] + $total_posts, true);
+ set_config_count('num_topics', sizeof($new_topic_id_list), true);
+ set_config_count('num_posts', $total_posts, true);
foreach ($new_topic_id_list as $topic_id => $new_topic_id)
{
diff --git a/phpBB/includes/mcp/mcp_queue.php b/phpBB/includes/mcp/mcp_queue.php
index e113cfc232..1a35524167 100644
--- a/phpBB/includes/mcp/mcp_queue.php
+++ b/phpBB/includes/mcp/mcp_queue.php
@@ -663,12 +663,12 @@ function approve_post($post_id_list, $id, $mode)
if ($total_topics)
{
- set_config('num_topics', $config['num_topics'] + $total_topics, true);
+ set_config_count('num_topics', $total_topics, true);
}
if ($total_posts)
{
- set_config('num_posts', $config['num_posts'] + $total_posts, true);
+ set_config_count('num_posts', $total_posts, true);
}
unset($topic_approve_sql, $topic_replies_sql, $post_approve_sql);
diff --git a/phpBB/includes/mcp/mcp_topic.php b/phpBB/includes/mcp/mcp_topic.php
index 931300897e..576d20b466 100644
--- a/phpBB/includes/mcp/mcp_topic.php
+++ b/phpBB/includes/mcp/mcp_topic.php
@@ -501,7 +501,7 @@ function split_topic($action, $topic_id, $to_forum_id, $subject)
$success_msg = 'TOPIC_SPLIT_SUCCESS';
// Update forum statistics
- set_config('num_topics', $config['num_topics'] + 1, true);
+ set_config_count('num_topics', 1, true);
// Link back to both topics
$return_link = sprintf($user->lang['RETURN_TOPIC'], '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $post_info['forum_id'] . '&amp;t=' . $post_info['topic_id']) . '">', '</a>') . '<br /><br />' . sprintf($user->lang['RETURN_NEW_TOPIC'], '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $to_forum_id . '&amp;t=' . $to_topic_id) . '">', '</a>');