*** ../../Downloads/simplenews/simplenews.module	2010-05-19 16:01:22.000000000 +0200
--- ./simplenews.module	2010-05-23 12:31:13.074899253 +0200
***************
*** 46,51 ****
--- 46,52 ----
  define('SIMPLENEWS_SPOOL_HOLD', 0);
  define('SIMPLENEWS_SPOOL_PENDING', 1);
  define('SIMPLENEWS_SPOOL_DONE', 2);
+ define('SIMPLENEWS_SPOOL_WORKING', 3);
  
  /**
   * AFTER EACH 100 NEWSLETTERS
***************
*** 1781,1786 ****
--- 1782,1806 ----
    $limit = isset($limit) ? $limit : variable_get('simplenews_throttle', 20);
    if ($messages = simplenews_get_spool(SIMPLENEWS_SPOOL_PENDING, $nid, $vid, $limit)) {
      $count_fail = $count_success = 0;
+     
+     // Update the spool and set the status in the pool on working, to prevent double selection
+     // also know as the poormans cron fix
+     // Maybe this is not the best solution?
+     // When get_spool is run in another instance, before the current items are on status working (on line 1798)
+     // they will be selected twice. It is probably better to update the status first and then fetch 
+     // the msids by affected rows.
+     $msids = array_keys($messages);
+     $status = array(
+       'status' => SIMPLENEWS_SPOOL_WORKING,
+       'error' => FALSE,
+     );
+     simplenews_update_spool($msids, $status);
+     
+     // set ignore user abort to keep running even if user stops execution
+     ignore_user_abort(TRUE);
+     
+     // register shutdown function to set the remaining msids with status working back to pending, so that they will be selected again on next run
+     register_shutdown_function('_simplenews_reset_spool', $msids);
  
      // Get PHP maximum execution time. 30 seconds default.
      $max_execution_time = ini_get('max_execution_time') ? ini_get('max_execution_time') : SIMPLENEWS_MAX_EXECUTION_TIME;
***************
*** 1923,1928 ****
--- 1943,1963 ----
  }
  
  /**
+  * Set status from working back to pending
+  * 
+  * When the spoolsend is stopped for whatever reason, the leftovers of the currently
+  * worked messages must be set back to pending, so that they will be selected on next cron run
+  */
+ function _simplenews_reset_spool($msids) {
+   $params = array(
+     SIMPLENEWS_SPOOL_PENDING,
+     SIMPLENEWS_SPOOL_WORKING
+   );
+   $params = array_merge($params, $msids);
+   db_query("UPDATE {simplenews_mail_spool} SET status = %d WHERE status = %d AND msid IN(". db_placeholders($msids, 'int') .")", $params);
+ }
+ 
+ /**
   * Update newsletter sent status.
   *
   * Set newsletter sent status based on email sent status in spool table.
