diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module index 0a7b261..9e0de11 100644 --- a/core/modules/comment/comment.module +++ b/core/modules/comment/comment.module @@ -2288,15 +2288,6 @@ function comment_alphadecimal_to_int($c = '00') { } /** - * Increments a sorting code to the next value. - * - * @see comment_int_to_alphadecimal() - */ -function comment_increment_alphadecimal($c = '00') { - return comment_int_to_alphadecimal(comment_alphadecimal_to_int($c) + 1); -} - -/** * Implements hook_action_info(). */ function comment_action_info() { diff --git a/core/modules/comment/lib/Drupal/comment/CommentStorageController.php b/core/modules/comment/lib/Drupal/comment/CommentStorageController.php index b041ebd..5f0ea78 100644 --- a/core/modules/comment/lib/Drupal/comment/CommentStorageController.php +++ b/core/modules/comment/lib/Drupal/comment/CommentStorageController.php @@ -50,7 +50,7 @@ class CommentStorageController extends DatabaseStorageController { * Overrides Drupal\entity\DatabaseStorageController::preSave(). * * @see comment_int_to_alphadecimal() - * @see comment_increment_alphadecimal() + * @see comment_alphadecimal_to_int() */ protected function preSave(EntityInterface $comment) { global $user; @@ -69,8 +69,12 @@ class CommentStorageController extends DatabaseStorageController { if (!empty($comment->thread)) { // Allow calling code to set thread itself. $thread = $comment->thread; + $need_lock = FALSE; } - elseif ($comment->pid == 0) { + else { + $prefix = ''; + $need_lock = TRUE; + if ($comment->pid == 0) { // This is a comment with no parent comment (depth 0): we start // by retrieving the maximum thread level. $max = db_query('SELECT MAX(thread) FROM {comment} WHERE nid = :nid', array(':nid' => $comment->nid))->fetchField(); @@ -78,9 +82,7 @@ class CommentStorageController extends DatabaseStorageController { $max = rtrim($max, '/'); // We need to get the value at the correct depth. $parts = explode('.', $max); - $firstsegment = $parts[0]; - // Finally, build the thread field for this new comment. - $thread = comment_increment_alphadecimal($firstsegment) .'/'; + $n = comment_alphadecimal_to_int($parts[0]); } else { // This is a comment with a parent comment, so increase the part of @@ -98,7 +100,7 @@ class CommentStorageController extends DatabaseStorageController { if ($max == '') { // First child of this parent. - $thread = $parent->thread . '.' . comment_int_to_alphadecimal(0) . '/'; + $n = -1; } else { // Strip the "/" at the end of the thread. @@ -106,10 +108,16 @@ class CommentStorageController extends DatabaseStorageController { // Get the value at the correct depth. $parts = explode('.', $max); $parent_depth = count(explode('.', $parent->thread)); - $last = $parts[$parent_depth]; - // Finally, build the thread field for this new comment. - $thread = $parent->thread . '.' . comment_increment_alphadecimal($last) . '/'; + $n = comment_alphadecimal_to_int($parts[$parent_depth]); + $prefix = $parent->thread . '.'; + } } + // Finally, build the thread field for this new comment. To avoid + // race conditions, get a lock on the thread. If aother process already + // has the lock, just increment the thread number. + do { + $thread = $prefix . comment_int_to_alphadecimal(++$n) . '/'; + } while (!lock_acquire("comment:$comment->nid:$thread")); } if (empty($comment->created)) { $comment->created = REQUEST_TIME;