diff --git a/modules/comment/comment.module b/modules/comment/comment.module
index 429c3b0..8abe01c 100644
--- a/modules/comment/comment.module
+++ b/modules/comment/comment.module
@@ -1493,47 +1493,55 @@ function comment_save($comment) {
       if (!empty($comment->thread)) {
         // Allow calling code to set thread itself.
         $thread = $comment->thread;
-      }
-      elseif ($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();
-        // Strip the "/" from the end of the thread.
-        $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 = int2vancode(vancode2int($firstsegment) + 1) . '/';
+        $need_lock = FALSE;
       }
       else {
-        // This is a comment with a parent comment, so increase the part of the
-        // thread value at the proper depth.
-
-        // Get the parent comment:
-        $parent = comment_load($comment->pid);
-        // Strip the "/" from the end of the parent thread.
-        $parent->thread = (string) rtrim((string) $parent->thread, '/');
-        // Get the max value in *this* thread.
-        $max = db_query("SELECT MAX(thread) FROM {comment} WHERE thread LIKE :thread AND nid = :nid", array(
-          ':thread' => $parent->thread . '.%',
-          ':nid' => $comment->nid,
-        ))->fetchField();
-
-        if ($max == '') {
-          // First child of this parent.
-          $thread = $parent->thread . '.' . int2vancode(0) . '/';
-        }
-        else {
-          // Strip the "/" at the end of the thread.
+        $prefix = '';
+        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();
+          // Strip the "/" from the end of the thread.
           $max = rtrim($max, '/');
-          // Get the value at the correct depth.
+          // We need to 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 . '.' . int2vancode(vancode2int($last) + 1) . '/';
+          $n = vancode2int($parts[0]);
+        }
+        else {
+          // This is a comment with a parent comment, so increase the part of the
+          // thread value at the proper depth.
+
+          // Get the parent comment:
+          $parent = comment_load($comment->pid);
+          // Strip the "/" from the end of the parent thread.
+          $parent->thread = (string) rtrim((string) $parent->thread, '/');
+          // Get the max value in *this* thread.
+          $max = db_query("SELECT MAX(thread) FROM {comment} WHERE thread LIKE :thread AND nid = :nid", array(
+            ':thread' => $parent->thread . '.%',
+            ':nid' => $comment->nid,
+          ))->fetchField();
+
+          if ($max == '') {
+            // First child of this parent.
+            $n = -1;
+          }
+          else {
+            // Strip the "/" at the end of the thread.
+            $max = rtrim($max, '/');
+            // Get the value at the correct depth.
+            $parts = explode('.', $max);
+            $parent_depth = count(explode('.', $parent->thread));
+            $n = vancode2int($parts[$parent_depth]);
+            $prefix = $parent->thread . '.';
+          }
         }
+        $need_lock = TRUE;
+        // We need a lopp here to avoid race conditions: if another process
+        // grabbed the same thread, just move to the next integer.
+        do {
+          // Finally, build the thread field for this new comment.
+          $thread = $prefix . int2vancode(++$n) . '/';
+        } while (!lock_acquire("comment:$comment->nid:$thread"));
       }
 
       if (empty($comment->created)) {
@@ -1558,6 +1566,9 @@ function comment_save($comment) {
       $comment->hostname = ip_address();
 
       drupal_write_record('comment', $comment);
+      if ($need_lock) {
+        lock_release("comment:$comment->nid:$thread");
+      }
 
       // Ignore slave server temporarily to give time for the
       // created comment to be propagated to the slave.
diff --git a/modules/simpletest/drupal_web_test_case.php b/modules/simpletest/drupal_web_test_case.php
index 251c5c1..45f4027 100644
--- a/modules/simpletest/drupal_web_test_case.php
+++ b/modules/simpletest/drupal_web_test_case.php
@@ -1563,6 +1563,11 @@ class DrupalWebTestCase extends DrupalTestCase {
 
     if (!isset($this->curlHandle)) {
       $this->curlHandle = curl_init();
+      // Some versions/configurations of cURL break on a NULL cookie jar, so
+      // supply a real file.
+      if (empty($this->cookieFile)) {
+        $this->cookieFile = variable_set('file_public_path', conf_path() . '/files') . '/cookie.jar';
+      }
       $curl_options = array(
         CURLOPT_COOKIEJAR => $this->cookieFile,
         CURLOPT_URL => $base_url,
@@ -1577,7 +1582,12 @@ class DrupalWebTestCase extends DrupalTestCase {
         $curl_options[CURLOPT_HTTPAUTH] = $this->httpauth_method;
         $curl_options[CURLOPT_USERPWD] = $this->httpauth_credentials;
       }
-      curl_setopt_array($this->curlHandle, $this->additionalCurlOptions + $curl_options);
+      // curl_setopt_array() returns FALSE if any of the specified options
+      // cannot be set, and stops processing any further options.
+      $result = curl_setopt_array($this->curlHandle, $this->additionalCurlOptions + $curl_options);
+      if (!$result) {
+        throw new UnexpectedValueException('One or more cURL options could not be set.');
+      }
 
       // By default, the child session name should be the same as the parent.
       $this->session_name = session_name();
