Roxen.git / server / base_server / roxen.pike

version» Context lines:

Roxen.git/server/base_server/roxen.pike:1:   // This file is part of Roxen WebServer.   // Copyright © 1996 - 2009, Roxen IS.   //   // The Roxen WebServer main program.   //   // Per Hedbor, Henrik Grubbström, Pontus Hagland, David Hedbor and others.   // ABS and suicide systems contributed freely by Francesco Chemolli    - constant cvs_version="$Id: roxen.pike,v 1.1089 2011/10/05 15:01:29 mast Exp $"; + constant cvs_version="$Id: roxen.pike,v 1.1090 2011/10/17 09:14:14 mast Exp $";      //! @appears roxen   //!   //! The Roxen WebServer main program.      // The argument cache. Used by the image cache.   ArgCache argcache;      // Some headerfiles   #define IN_ROXEN
Roxen.git/server/base_server/roxen.pike:1080:    return;    }   }      protected Thread.MutexKey backend_block_lock;      void stop_handler_threads()   //! Stop all the handler threads and the backend, but give up if it   //! takes too long.   { -  int timeout=10; +  int timeout=15; // Timeout if the bg queue doesn't get shorter. +  int background_run_timeout = 100; // Hard timeout that cuts off the bg queue.   #if constant(_reset_dmalloc)    // DMALLOC slows stuff down a bit...    timeout *= 10; -  +  background_run_timeout *= 3;   #endif /* constant(_reset_dmalloc) */ -  +     report_debug("Stopping all request handler threads.\n");       // Wake up any handler threads on hold, and ensure none gets on hold    // after this.    if (Thread.Condition cond = hold_wakeup_cond) {    hold_wakeup_cond = 0;    cond->broadcast();    }       while(number_of_threads>0) {
Roxen.git/server/base_server/roxen.pike:1113:    Thread.Mutex mutex = Thread.Mutex();    backend_block_lock = mutex->lock();    call_out (lambda () {    thread_reap_cnt--;    report_debug("Backend thread stopped.\n");    mutex->lock();    error("Backend stop failed.\n");    }, 0);    }    -  while(thread_reap_cnt) { +  int prev_bg_len = bg_queue_length(); +  +  while (thread_reap_cnt) {    sleep(0.1); -  if(--timeout<=0) { +  +  if (--timeout <= 0) { +  int cur_bg_len = bg_queue_length(); +  if (prev_bg_len < cur_bg_len) +  // Allow more time if the background queue is being worked off. +  timeout = 10; +  prev_bg_len = cur_bg_len; +  } +  +  if(--background_run_timeout <= 0 || timeout <= 0) {    report_debug("Giving up waiting on threads; " -  "%d threads blocked.\n", thread_reap_cnt); +  "%d threads blocked, %d jobs in the background queue.\n", +  thread_reap_cnt, bg_queue_length());   #ifdef DEBUG    describe_all_threads();   #endif    return;    }    }   }      #else   // handle function used when THREADS is not enabled.
Roxen.git/server/base_server/roxen.pike:1259: Inside #if defined(THREADS)
   mixed call_out;   #endif       if (mixed err = catch {    // Make sure we don't run forever if background jobs are queued    // over and over again, to avoid starving other threads. (If they    // are starved enough, busy_threads will never be incremented.)    // If jobs are enqueued while running another background job,    // bg_process_queue is put on the handler queue again at the very    // end of this function. +  // +  // However, during shutdown we continue until the queue is really +  // empty. background_run won't queue new jobs then, and if this +  // takes too long, stop_handler_threads will exit anyway.    int jobs_to_process = bg_queue->size(); -  while (jobs_to_process-- && !shutdown_started) { +  while (hold_wakeup_cond ? jobs_to_process-- : bg_queue->size()) {    // Not a race here since only one thread is reading the queue.    array task = bg_queue->read();       // Wait a while if another thread is busy already.    if (busy_threads > 1) {    for (maxbeats = max (maxbeats, (int) (bg_time_buffer_min / 0.01));    busy_threads > 1 && maxbeats > 0;    maxbeats--)    sleep (0.01);    bg_last_busy = time();
Roxen.git/server/base_server/roxen.pike:1423: Inside #if defined(DEBUG_BACKGROUND_RUN)
   programp (func) ?    sprintf ("%s: %s", Program.defined (func),    master()->describe_program (func)) :    sprintf ("%O", func),    map (args, lambda (mixed arg)    {return sprintf ("%O", arg);}) * ", ",    bg_queue->size());   #endif      #ifdef THREADS -  if (!hold_wakeup_cond) +  if (!hold_wakeup_cond) {    // stop_handler_threads is running; ignore more work. -  + #ifdef DEBUG +  report_debug ("Ignoring background job queued during shutdown: %O\n", func); + #endif    return 0; -  +  }       class enqueue(function func, mixed ... args)    {    int __hash() { return hash_value(func); }    int `==(mixed gunc) { return func == gunc; }    string _sprintf() { return sprintf("background_run(%O)", func); }    mixed `()()    {    bg_queue->write (({func, args}));    if (!bg_process_thread)