5 common.inc drupal_cron_run()
6 common.inc drupal_cron_run()
7 common.inc drupal_cron_run()

Executes a cron run when called.

Do not call this function from a test. Use $this->cronRun() instead.

Return value

bool TRUE if cron ran successfully and FALSE if cron is already running.

8 calls to drupal_cron_run()
cron.php in ./cron.php
Handles incoming requests to fire off regularly-scheduled tasks (cron jobs).
CronRunTestCase::testCronCacheExpiration in modules/system/system.test
Tests that hook_flush_caches() is not invoked on every single cron run.
DrupalWebTestCase::setUp in modules/simpletest/drupal_web_test_case.php
Sets up a Drupal site for running functional and integration tests.
install_finished in includes/install.core.inc
Finishes importing files at end of installation.
PollExpirationTestCase::testAutoExpire in modules/poll/poll.test

... See full list


includes/common.inc, line 5329
Common functions that many Drupal modules will need to reference.


function drupal_cron_run() {
  // Allow execution to continue even if the request gets canceled.

  // Prevent session information from being saved while cron is running.
  $original_session_saving = drupal_save_session();

  // Force the current user to anonymous to ensure consistent permissions on
  // cron runs.
  $original_user = $GLOBALS['user'];
  $GLOBALS['user'] = drupal_anonymous_user();

  // Try to allocate enough time to run all the hook_cron implementations.

  $return = FALSE;
  // Grab the defined cron queues.
  $queues = module_invoke_all('cron_queue_info');
  drupal_alter('cron_queue_info', $queues);

  // Try to acquire cron lock.
  if (!lock_acquire('cron', 240.0)) {
    // Cron is still running normally.
    watchdog('cron', 'Attempting to re-run cron while it is already running.', array(), WATCHDOG_WARNING);
  else {
    // Make sure every queue exists. There is no harm in trying to recreate an
    // existing queue.
    foreach ($queues as $queue_name => $info) {

    // Iterate through the modules calling their cron handlers (if any):
    foreach (module_implements('cron') as $module) {
      // Do not let an exception thrown by one module disturb another.
      try {
        module_invoke($module, 'cron');
      catch (Exception $e) {
        watchdog_exception('cron', $e);

    // Record cron time.
    variable_set('cron_last', REQUEST_TIME);
    watchdog('cron', 'Cron run completed.', array(), WATCHDOG_NOTICE);

    // Release cron lock.

    // Return TRUE so other functions can check if it did run successfully
    $return = TRUE;

  foreach ($queues as $queue_name => $info) {
    if (!empty($info['skip on cron'])) {
      // Do not run if queue wants to skip.
    $callback = $info['worker callback'];
    $end = time() + (isset($info['time']) ? $info['time'] : 15);
    $queue = DrupalQueue::get($queue_name);
    while (time() < $end && ($item = $queue->claimItem())) {
      try {
        call_user_func($callback, $item->data);
      catch (Exception $e) {
        // In case of exception log it and leave the item in the queue
        // to be processed again later.
        watchdog_exception('cron', $e);
  // Restore the user.
  $GLOBALS['user'] = $original_user;

  return $return;


I don't understand:
In the code above, on every cron run, the Queue is (re)created with:

// Make sure every queue exists. There is no harm in trying to recreate an
    // existing queue.
foreach ($queues as $queue_name => $info) {

but in DrupalQueueInterface::createQueue() it says:

Create a queue.

Called during installation and should be used to perform any necessary initialization operations. This should not be confused with the constructor for these objects, which is called every time an object is instantiated to operate on a queue. This operation is only needed the first time a given queue is going to be initialized (for example, to make a new database table or directory to hold tasks for the queue -- it depends on the queue implementation if this is necessary at all).

How can "be no harm" to (re)create queue on each cron run?!?!
As far as I understand the queue should only be processed by drupal_cron_run() not (re)created on every cron.

Being that the DrupalQueueInterface is an interface, it defines the "createQueue" function, which actually does nothing for the DrupalQueue class, other than assure that the created queues implement the function. The function is empty for the SystemQueue class, which is most likely what you are using behind the scenes. Therefore, from what I can see, there is really no need to call the function, but there is no harm either. The benefit might be if at some point, a different class was used from within the DrupalQueue::get(), which actually did something to create the queue (like initializations ...), and would most likely check to see if it has already been created. This could be the case if a different queue class was set as the default. The public function "get" from the DrupalQueue class is what actually creates the queue object, by calling the specified class, but only if it does not exist.