Пример #1
0
/****** uti/tq/sge_tq_store_notify() *******************************************
*  NAME
*     sge_tq_store_notify() -- Appends a new task at the end of queue 
*
*  SYNOPSIS
*     bool 
*     sge_tq_store_notify(sge_tq_queue_t *queue, 
*                         sge_tq_type_t type, void *data) 
*
*  FUNCTION
*     This function creates a new task using 'type' and 'data'. The new
*     task will then be appended to 'queue'. If there are threads waiting
*     in sge_tq_wait_for_task() then one of those waiting threads will be
*     triggered so that it will wake up. 
*
*     If there are multiple threads waiting then it might happen that
*     always the same thread wakes up to catch the task (starvation).
*
*  INPUTS
*     sge_tq_queue_t *queue - task queue 
*     sge_tq_type_t type    - task type 
*     void *data            - task data
*
*  RESULT
*     bool - error state
*        true  - success
*        false - error
*
*  NOTES
*     MT-NOTE: sge_tq_store_notify() is MT safe 
*
*  SEE ALSO
*     uti/tq/sge_tq_wait_for_task() 
*******************************************************************************/
bool
sge_tq_store_notify(sge_tq_queue_t *queue, sge_tq_type_t type, void *data) {
   bool ret = true;

   DENTER(TQ_LAYER, "sge_tq_store_notify");
   if (queue != NULL && type != SGE_TQ_UNKNOWN && data != NULL) {
      sge_tq_task_t *new_task = NULL;

      /* create a new task */
      ret &= sge_tq_task_create(&new_task, type, data); 

      /* insert the task in the list and notify one waiting thread if there is one */ 
      sge_mutex_lock(TQ_MUTEX_NAME, SGE_FUNC, __LINE__, sge_sl_get_mutex(queue->list));
      if (ret) {
         ret = sge_sl_insert(queue->list, new_task, SGE_SL_BACKWARD);
      }
      if (ret && queue->waiting > 0) {
         sge_tq_wakeup_waiting(queue);
      }
      sge_mutex_unlock(TQ_MUTEX_NAME, SGE_FUNC, __LINE__, sge_sl_get_mutex(queue->list));
   }
   DRETURN(ret);
}
void
sge_worker_terminate(sge_gdi_ctx_class_t *ctx)
{
   bool do_final_spooling;

   DENTER(TOP_LAYER, "sge_worker_terminate");

   sge_tq_wakeup_waiting(Master_Task_Queue);

   /*
    * trigger pthread_cancel for each thread so that further 
    * shutdown process will be faster
    */
   {
      cl_thread_list_elem_t *thr = NULL;
      cl_thread_list_elem_t *thr_nxt = NULL;

      thr_nxt = cl_thread_list_get_first_elem(Main_Control.worker_thread_pool);
      while ((thr = thr_nxt) != NULL) {
         thr_nxt = cl_thread_list_get_next_elem(thr);

         cl_thread_shutdown(thr->thread_config); 
      }
   }

   /*
    * Shutdown/delete the threads and wait for termination
    */
   {
      cl_thread_settings_t *thread = NULL;

      thread = cl_thread_list_get_first_thread(Main_Control.worker_thread_pool);
      while (thread != NULL) {
         DPRINTF(("gets canceled\n"));
         cl_thread_list_delete_thread(Main_Control.worker_thread_pool, thread);

         thread = cl_thread_list_get_first_thread(Main_Control.worker_thread_pool);
      }  
      DPRINTF(("all "SFN" threads terminated\n", threadnames[WORKER_THREAD]));
   }

   do_final_spooling = sge_qmaster_do_final_spooling();

   /* shutdown and remove JSV instances */
   jsv_list_remove_all();

   reporting_shutdown(ctx, NULL, do_final_spooling);
   DPRINTF(("accounting and reporting module has been shutdown\n"));

   /*
    * final spooling is only done if the shutdown of the current instance
    * of this master process is not triggered due to the fact that
    * shadowed started another instance which is currently running ...
    *
    * ... in that case we would overwrite data which might have already
    * changed in the second instance of the master
    */
   if (do_final_spooling == true) {
      sge_store_job_number(ctx, NULL, NULL);
      sge_store_ar_id(ctx, NULL, NULL);
      DPRINTF(("job/ar counter made persistent\n"));
      sge_job_spool(ctx);     /* store qmaster jobs to database */
      sge_userprj_spool(ctx); /* spool the latest usage */
      DPRINTF(("final job and user/project spooling has been triggered\n"));
   }

   sge_shutdown_persistence(NULL);
   DPRINTF(("persistence module has been shutdown\n"));

   DRETURN_VOID;
}