#include "license_pbs.h" /* See here for the software license */
#include <pbs_config.h>   /* the master config generated by configure */
#include "queue_recycler.h"

#include "queue.h" /* pbs_queue, all_queues */
#include "queue_func.h"
#include "mutex_mgr.hpp"


#include "utils.h"
#include "threadpool.h"
#include "mutex_mgr.hpp"

extern queue_recycler q_recycler;
extern int LOGLEVEL;


pbs_queue *next_queue_from_recycler(
    
  all_queues           *aq,
  all_queues_iterator  *iter)

  {
  pbs_queue *pq;

  aq->lock();
  pq = iter->get_next_item();
  if (pq != NULL)
    lock_queue(pq, __func__, NULL, LOGLEVEL);
  aq->unlock();

  return(pq);
  } /* END next_queue_from_recycler() */




void *remove_some_recycle_queues(

  void *vp)

  {
  all_queues_iterator *iter = NULL;
  pbs_queue *pq;

  q_recycler.queues.lock();
  iter = q_recycler.queues.get_iterator();
  q_recycler.queues.unlock();
  mutex_mgr q_recycler_mutex = mutex_mgr(q_recycler.mutex, false);

  pq = next_queue_from_recycler(&q_recycler.queues,iter);

  delete iter;

  if (pq == NULL)
    return NULL;

  remove_queue(&q_recycler.queues,pq);
  unlock_queue(pq, __func__, NULL, LOGLEVEL);
  free(pq->qu_mutex);
  delete pq->qu_jobs;
  delete pq->qu_jobs_array_sum;
  memset(pq, 254, sizeof(pbs_queue));
  free(pq);

  return(NULL);
  } /* END remove_some_recycle_queues() */




int insert_into_queue_recycler(

  pbs_queue *pq)

  {
  int              rc;

  pthread_mutex_lock(q_recycler.mutex);

  memset(pq->qu_qs.qu_name, 0, sizeof(pq->qu_qs.qu_name));
  sprintf(pq->qu_qs.qu_name,"%d",q_recycler.next_id);
  pq->q_being_recycled = TRUE;

  q_recycler.queues.lock();
  if (q_recycler.queues.count() >= MAX_RECYCLE_QUEUES)
    {
    enqueue_threadpool_request(remove_some_recycle_queues, NULL, task_pool);
    }
  q_recycler.queues.unlock();

  rc = insert_queue(&q_recycler.queues,pq);

  update_queue_recycler_next_id();

  pthread_mutex_unlock(q_recycler.mutex);

  return(rc);
  } /* END insert_into_queue_recycler() */




void update_queue_recycler_next_id()

  {
  if (q_recycler.next_id >= q_recycler.max_id)
    q_recycler.next_id = 0;
  else
    q_recycler.next_id++;
  } /* END update_queue_recycler_next_id() */

