Index: modules/comment/comment.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v
retrieving revision 1.870
diff -u -r1.870 comment.module
--- modules/comment/comment.module	24 Apr 2010 14:49:13 -0000	1.870
+++ modules/comment/comment.module	24 Apr 2010 16:53:06 -0000
@@ -1522,39 +1522,86 @@
 }
 
 /**
- * Delete a comment and all its replies.
+ * Deletes a comment and all its replies.
  *
  * @param $cid
- *   The comment to delete.
+ *   The id of the comment to delete.
+ *
+ * @see comment_delete_multiple()
  */
 function comment_delete($cid) {
-  comment_delete_multiple(array($cid));
+  if ($comment = comment_load($cid)) {
+    // Delete the comment.
+    db_delete('comment')
+      ->condition('cid', $comment->cid)
+      ->execute();
+
+    field_attach_delete('comment', $comment);
+    module_invoke_all('comment_delete', $comment);
+
+    // Delete the comment's replies.
+    $child_cids = db_query('SELECT cid FROM {comment} WHERE pid = :cid', array(':cid' => $comment->cid))->fetchCol();
+    comment_delete_multiple($child_cids);
+    _comment_update_node_statistics($comment->nid);
+  }
 }
 
 /**
- * Delete comments and all their replies.
+ * Deletes comments and all their replies.
+ *
+ * Comments to be deleted are queued, and queue processing starts immediately.
+ * If this process is aborted before completion, the remaining commentswill be
+ * deleted during subsequent cron runs.
  *
  * @param $cids
  *   The comment to delete.
+ *
+ * @see comment_delete()
  */
 function comment_delete_multiple($cids) {
-  $comments = comment_load_multiple($cids);
-  if ($comments) {
+  variable_set('queue_class_comment_deletes', 'BatchQueue');
+  $queue = DrupalQueue::get('comment_deletes');
+  $queue->createQueue();
 
-    // Delete the comments.
-    db_delete('comment')
-      ->condition('cid', array_keys($comments), 'IN')
-      ->execute();
-    foreach ($comments as $comment) {
-      field_attach_delete('comment', $comment);
-      module_invoke_all('comment_delete', $comment);
-
-      // Delete the comment's replies.
-      $child_cids = db_query('SELECT cid FROM {comment} WHERE pid = :cid', array(':cid' => $comment->cid))->fetchCol();
-      comment_delete_multiple($child_cids);
-      _comment_update_node_statistics($comment->nid);
-    }
+  foreach ($cids as $cid) {
+    $queue->createItem($cid);
+  }
+
+  // Start processing the comments to be deleted. If interupted before
+  // completion, the remaining comments will be deleted during the next cron
+  // runs.
+  while ($item = $queue->claimItem()) {
+    comment_delete($item->data);
+    $queue->deleteItem($item);
   }
+
+}
+
+/**
+ * Worker callback for comment deletions.
+ *
+ * @param $item
+ *   A queue item representing the comment to be deleted.
+ */
+function _comment_delete($item) {
+  static $queue;
+
+  if (!isset($queue)) {
+    $queue = DrupalQueue::get('comment_deletes');
+  }
+
+  comment_delete($item->data);
+  $queue->deleteItem($item);
+}
+
+/**
+ * Implementation of hook_cron_queue_info().
+ */
+function comment_cron_queue_info() {
+  $queues['comment_deletes'] = array(
+    'worker_callback' => '_comment_delete',
+    'time' => 1,
+  );
 }
 
 /**
Index: modules/node/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.module,v
retrieving revision 1.1264
diff -u -r1.1264 node.module
--- modules/node/node.module	22 Apr 2010 09:12:35 -0000	1.1264
+++ modules/node/node.module	24 Apr 2010 16:53:07 -0000
@@ -445,7 +445,7 @@
  *
  * All new module-defined node types are saved to the database via a call to
  * node_type_save(), and obsolete ones are deleted via a call to
- * node_type_delete(). See _node_types_build() for an explanation of the new 
+ * node_type_delete(). See _node_types_build() for an explanation of the new
  * and obsolete types.
  */
 function node_types_rebuild() {
@@ -1117,54 +1117,103 @@
 }
 
 /**
- * Delete a node.
+ * Deletes a single node.
  *
  * @param $nid
  *   A node ID.
+ *
+ * @see node_delete_multiple()
  */
 function node_delete($nid) {
-  node_delete_multiple(array($nid));
+  if ($node = node_load($nid)) {
+    db_delete('node')
+      ->condition('nid', $nid)
+      ->execute();
+    db_delete('node_revision')
+      ->condition('nid', $nid)
+      ->execute();
+    db_delete('history')
+      ->condition('nid', $nid)
+      ->execute();
+
+    // Call the node-specific callback (if any):
+    node_invoke($node, 'delete');
+    module_invoke_all('node_delete', $node);
+    field_attach_delete('node', $node);
+
+    // Remove this node from the search index if needed.
+    // This code is implemented in node module rather than in search module,
+    // because node module is implementing search module's API, not the other
+    // way around.
+    if (module_exists('search')) {
+      search_reindex($nid, 'node');
+    }
+
+    // Clear the page and block and node_load_multiple caches.
+    cache_clear_all();
+    entity_get_controller('node')->resetCache();
+  }
 }
 
 /**
- * Delete multiple nodes.
+ * Deletes multiple nodes.
+ *
+ * Nodes to be deleted are queued, and queue processing starts immediately.
+ * If this process is aborted before completion, the remaining nodes will be
+ * deleted during subsequent cron runs.
  *
  * @param $nids
  *   An array of node IDs.
+ *
+ * @see node_delete()
  */
 function node_delete_multiple($nids) {
   if (!empty($nids)) {
     $nodes = node_load_multiple($nids, array());
 
-    db_delete('node')
-      ->condition('nid', $nids, 'IN')
-      ->execute();
-    db_delete('node_revision')
-      ->condition('nid', $nids, 'IN')
-      ->execute();
-    db_delete('history')
-      ->condition('nid', $nids, 'IN')
-      ->execute();
+    variable_set('queue_class_node_deletes', 'BatchQueue');
+    $queue = DrupalQueue::get('node_deletes');
+    $queue->createQueue();
 
-    foreach ($nodes as $nid => $node) {
-      // Call the node-specific callback (if any):
-      node_invoke($node, 'delete');
-      module_invoke_all('node_delete', $node);
-      field_attach_delete('node', $node);
-
-      // Remove this node from the search index if needed.
-      // This code is implemented in node module rather than in search module,
-      // because node module is implementing search module's API, not the other
-      // way around.
-      if (module_exists('search')) {
-        search_reindex($nid, 'node');
-      }
+    foreach ($nids as $nid) {
+      $queue->createItem($nid);
     }
 
-    // Clear the page and block and node_load_multiple caches.
-    cache_clear_all();
-    entity_get_controller('node')->resetCache();
+    // Start processing the nodes to be deleted. If interupted before
+    // completion, the remaining nodes will be deleted during the next cron
+    // runs.
+    while ($item = $queue->claimItem()) {
+      node_delete($item->data);
+      $queue->deleteItem($item);
+    }
+  }
+}
+
+/**
+ * Worker callback for node deletions.
+ *
+ * @param $item
+ *   A queue item representing the node to be deleted.
+ */
+function _node_delete($item) {
+  static $queue;
+
+  if (!isset($queue)) {
+    $queue = DrupalQueue::get('node_deletes');
   }
+
+  node_delete($item->data);
+  $queue->deleteItem($item);
+}
+
+/**
+ * Implementation of hook_cron_queue_info().
+ */
+function node_cron_queue_info() {
+  $queues['node_deletes'] = array(
+    'worker_callback' => '_node_delete',
+    'time' => 1,
+  );
 }
 
 /**
