Beispiel #1
0
int queue_count_status(list_t *queue_list, int status)
{
  node_t                *node;
  queue_node_t          *queue_node;
  int                   matching_jobs = 0;

  list_lock(queue_list);

  if (queue_list->n == 0) {
    list_unlock(queue_list);
    return 0;
  }

  node = queue_list->head;

  for (;;) {
    queue_node = node->data;

    if (queue_node->queue_status == status)
      matching_jobs++;

    if (node->next == NULL)
      break;

    node = node->next;
  }

  list_unlock(queue_list);

  return matching_jobs;
}
Beispiel #2
0
void* queue_findfile(list_t *queue_list, char *file)
{
  node_t               *node;
  queue_node_t         *queue_node;

  list_lock(queue_list);

  if (queue_list->n == 0) {
    list_unlock(queue_list);
    return NULL;
  }

  node = queue_list->head;

  for (;;) {
    queue_node = node->data;

    //if (queue_node->queue_status != QSTAT_FINISHED) {
      if (!strcmp(file, (const char *) queue_node->nzb->path)) {
        return queue_node;
      }
    //}

    if (node->next == NULL)
      break;

    node = node->next;
  }

  list_unlock(queue_list);

  return NULL;
}
Beispiel #3
0
void msg_free(message_t *message)
{
  list_t *message_queue;
  node_t *node;
  message_t *mnode;
  int found = 0;

  message_queue = msg_get_queue_ptr();

  list_lock(message_queue);

  DEBUG(4, "trying to free message %p", message);

  if (message_queue->n == 0) {
    DEBUG(4, "message queue is empty!");
    list_unlock(message_queue);
    return;
  }

  node = message_queue->head;

  for (;;) {

    if (node->data == message) {
      mnode = node->data;

      found = 1;

      DEBUG(4, "found message %p (node %p, list %p), freeing..", message, mnode, message_queue);

      if (mnode->keep_pointers == 0) {
        if (mnode->arg_ptr != NULL) {
          DEBUG(4, "freeing message arg_ptr %p", mnode->arg_ptr);
          free(mnode->arg_ptr);
        }
        if (mnode->arg_list != NULL)
          DEBUG(4, "freeing message arg_list %p", mnode->arg_list);
          free(mnode->arg_list);
      }

      free(node->data);
      list_unlink(message_queue, node);
      break;
    }
   
    if ((node = node->next) == NULL)
      break;

  }

  if (found == 0)
    DEBUG(4, "message %p NOT found in message queue, not freed");

  list_unlock(message_queue);
 
  return;
}
Beispiel #4
0
static ssize_t data_format_t_convert_to(data_t *src, fastcall_convert_to *fargs){ // {{{
	ssize_t                ret;
	format_t               value;
	uintmax_t              transfered;
	keypair_t             *kp;
	void                  *iter              = NULL;
	char                  *string            = "(unknown)";
	
	if(fargs->dest == NULL || src->ptr == NULL)
		return -EINVAL;
	
	value = *(format_t *)src->ptr;
	
	switch(fargs->format){
		case FORMAT(config):;
		case FORMAT(clean):;
		case FORMAT(human):;
			// find in static keys first
			for(kp = &formats[0]; kp->key_str != NULL; kp++){
				if(kp->key_val == value){
					string = kp->key_str;
					goto found;
				}
			}
			
		#ifdef RESOLVE_DYNAMIC_KEYS
			// find in dynamic keys
			list_rdlock(&dynamic_formats);
			while( (kp = list_iter_next(&dynamic_formats, &iter)) != NULL){
				if(kp->key_val == value){
					string = kp->key_str;
					list_unlock(&dynamic_formats);
					goto found;
				}
			}
			list_unlock(&dynamic_formats);
		#endif
		
		found:;
			fastcall_write r_write = { { 5, ACTION_WRITE }, 0, string, strlen(string) };
			ret        = data_query(fargs->dest, &r_write);
			transfered = r_write.buffer_size;
			break;
		
		default:
			return -ENOSYS;
	}
	if(fargs->header.nargs >= 5)
		fargs->transfered = transfered;
	
	return ret;
} // }}}		
Beispiel #5
0
void list_sort(List *list, int(*cmp)(const void *, const void *))
{
    gw_assert(list != NULL && cmp != NULL);

    list_lock(list);
    if (list->len == 0) {
        /* nothing to sort */
        list_unlock(list);
        return;
    }
    qsort(&GET(list, 0), list->len, sizeof(void*), cmp);
    list_unlock(list);
}
Beispiel #6
0
unsigned int msg_send(int from, int to, int msg_id, void *arg_ptr, list_t *arg_list, int keep_pointers)
{
  list_t       *message_queue;
  message_t    *message;

  DEBUG(4, "sending message from %d to %d; msg_id=%d, arg_ptr=%p, arg_list=%p, keep_pointers=%d", from, to, msg_id, arg_ptr, arg_list, keep_pointers);

  message_queue = msg_get_queue_ptr();

  list_lock(message_queue);

  message = xmalloc(sizeof (message_t));

  DEBUG(4, "new message allocated at %p", message);

  message->from = from;
  message->to = to;
  message->msg_id = msg_id;
  message->arg_ptr = arg_ptr;
  message->arg_list = arg_list;
  message->ctime = time(NULL);
  message->atime = 0;
  message->keep_pointers = keep_pointers;

  list_push(message_queue, message);

  DEBUG(4, "message %p on list %p", message, message_queue);

  list_unlock(message_queue);

  return 1;
}
Beispiel #7
0
void list_add(LIST *list, void *data) {
	if (!list) {
		Ldbg(stderr, "list_add(), list == NULL\n");
		return;
	}

	if (!data) {
		Ldbg(stderr, "list_add(%s), data == NULL\n", list->name);
		return;
	}

	LNODE *node = calloc(1, sizeof(LNODE));
	if (!node) {
		Ldbg(stderr, "list_add(%s), can't alloc node\n", list->name);
		return;
	}

	node->data = data;

//	if (strcmp(list->name, "clients") == 0 || strcmp(list->name, "r->clients") == 0)
	Ldbg(stderr, "list_add(%s), node=%p data=%p\n", list->name, node, node->data);

	list_lock(list);

	node->prev = list->tail;
	node->next = list->head;

	list->tail->next = node;
	list->tail = node;
	list->head->prev = node;

	list->items++;
	list_unlock(list);
}
Beispiel #8
0
message_t* msg_recv(int recipient)
{
  list_t       *message_queue;
  node_t       *node;
  message_t    *message;
  time_t       time_now;

  message_queue = msg_get_queue_ptr();

  DEBUG(4, "looking for messages for recipient %d", recipient);

  list_lock(message_queue);

  if (message_queue->n == 0) {
    DEBUG(4, "message queue is empty!");
    list_unlock(message_queue);
    return NULL;
  }

  node = message_queue->head;

  time_now = time(NULL);

  for (;;) {
    message = node->data;

    /* check for new (atime=0) message to recipient */
    if ((int) message->to == recipient && message->atime == 0) {
      DEBUG(4, "message for recipient %d found at message %p (node %p, list %p)", recipient, message, node, message_queue);

      message->atime = time(NULL);
      list_unlock(message_queue);
      return message;
    }

    if ((node = node->next) == NULL)
      break;
  }

  DEBUG(4, "no message for recipient %d found", recipient);

  list_unlock(message_queue);

  return NULL;
}
/**
 * Removes the oldest job (message) from the queue and "runs" it. 
 *
 * @return 1 if a job was processed, 0 if the queue was empty. 
 */
static int
wombatThrottle_sendQueuedMessage (wombatThrottle throttle)
{
    MsgProperties *info;

    list_lock (self->mMsgQueue);
    if (NULL != (info = list_pop_front (self->mMsgQueue)))
    {
        /* Process a throttled message.*/
        info->mActionCb (info->mClosure1, info->mClosure2);
        list_free_element (self->mMsgQueue, info);
        list_unlock (self->mMsgQueue);
        return 1;
    }

    list_unlock (self->mMsgQueue);
    /* We did not send a message. */
    return 0;
}
Beispiel #10
0
unsigned int msg_send_to_type(int from, int to_type, int msg_id, void *arg_ptr, list_t *arg_list, int keep_pointers)
{
  list_t           *thread_list;
  node_t           *node;
  thread_node_t    *thread_node;
  unsigned int     send_count = 0;

  DEBUG(4, "message from %d to TYPE %d, searching for recipients", from, to_type);

  thread_list = get_thread_list_ptr();

  list_lock(thread_list);

  if (thread_list->n == 0) {
    DEBUG(4, "thread list is empty!");
    list_unlock(thread_list);
    return 0;
  }

  node = thread_list->head;

  for (;;) {
    thread_node = node->data;

    if (thread_node->thread_type == to_type) {
      DEBUG(4, "found thread %d of type %d, calling msg_send()", thread_node->tp, to_type);
      msg_send(from, (int)thread_node->tp, msg_id, arg_ptr, arg_list, keep_pointers);
      send_count++;
    }

    if ((node = node->next) == NULL)
      break;
  }

  DEBUG(4, "done searching for recipients, did %d call(s) to msg_send()", send_count);

  list_unlock(thread_list);

  return send_count;
}
mama_status
wombatThrottle_removeMessagesFromList (wombatThrottle throttle, wList list)
{
    gRemoveCount = 0;

    list_lock (self->mMsgQueue);
    list_for_each (list, removeMessagesFromListCb, self);
    mama_log (MAMA_LOG_LEVEL_FINE, "wombatThrottle_removeMessagesFromList (): "
              "%d Messages removed from queue list.",
              gRemoveCount);

    list_unlock (self->mMsgQueue);
    return MAMA_STATUS_OK;
}
Beispiel #12
0
static worker_node_t *do_get_worker(int create)
{
    node_t          *node;
    list_t          *thread_list;
    thread_node_t   *tn;
    worker_node_t   *w;

    thread_list = get_thread_list_ptr();
    
    list_lock(thread_list);
    for (node = thread_list->head; node != NULL ; node = node->next) {
        tn = node->data;

        if (tn->thread_type != TT_DL_WORKER)
            continue;

        if (tn->status == WSTAT_IDLE) {
            /* found idle worker, mark as active */
            tn->status = WSTAT_ACTIVE; 
            list_unlock(thread_list);
            return tn;
        }

    } /* end traverse linked list */
    list_unlock(thread_list);

    /* found no idle workers, spawn one if create is defined */

    if (create == 1) {
        /* found no free workers, spawn one, mark as active */
        tn = spawn_thread(thread_list, TT_DL_WORKER, dlworker, NULL);
        tn->status = WSTAT_ACTIVE;
        return tn;
    }

    return NULL;
}
Beispiel #13
0
void alog_close(void)
{

    if (file != NULL) {
        if (markers)
            alog("Log ends");
        list_lock(writers);
        /* wait for writers to complete */
        list_consume(writers);
        fclose(file);
        file = NULL;
        list_unlock(writers);
        list_destroy(writers, NULL);
        writers = NULL;
    }
}
Beispiel #14
0
void list_free(LIST **plist, void (*free_func)(void *), void (*freep_func)(void **)) {
	LIST *list = *plist;
	if (!list)
		return;
	Ldbg(stderr, "list_free(%s)\n", list->name);
	LNODE *node, *tmp;
	list_lock(list);
	list_for_each(list, node, tmp) {
		if (free_func && node->data)
			free_func(node->data);
		if (freep_func && node->data)
			freep_func(&node->data);
		list_del_unlocked(list, &node);
	}
	FREE(list->head);
	list_unlock(list);
	pthread_mutex_destroy(&list->mutex);
	FREE(list->name);
	FREE(*plist);
}
Beispiel #15
0
void alog(const char *fmt, ...)
{
    char buf[FORMAT_SIZE + 1];
    va_list args;

    if (file == NULL)
        return;

    format(buf, fmt);
    va_start(args, fmt);

    list_lock(writers);
    list_add_producer(writers);
    list_unlock(writers);

    vfprintf(file, buf, args);
    fflush(file);

    list_remove_producer(writers);

    va_end(args);
}
Beispiel #16
0
void alog_reopen(void)
{
    if (file == NULL)
	return;

    if (markers)
        alog("Log ends");

    list_lock(writers);
    /* wait for writers to complete */
    list_consume(writers);

    fclose(file);
    file = fopen(filename, "a");

    list_unlock(writers);

    if (file == NULL) {
        error(errno, "Couldn't re-open access logfile `%s'.", filename);
    } 
    else if (markers) {
        alog("Log begins");
    }
}
Beispiel #17
0
/*
 * Set tid for an existing initiator. Input a cache item and the new tid.
 */
static void set_tid_by_item(WTPCached_tid *item, long tid)
{
    list_lock(tid_cache);
    item->tid = tid;
    list_unlock(tid_cache);
}
Beispiel #18
0
int queue_add_entry(list_t *queue_list, char *path, int status, int options)
{
  queue_node_t            *queue_node;
  FILE                    *fp;
  int                     db_id;


  /* can we open it? */
  if ((fp = fopen(path, "r")) == NULL) {
    DEBUG(1, "Failed to queue file `%s': %s", path, strerror(errno));
    INFO(2, "Failed to queue file `%s': %s", path, strerror(errno));
    return 1;
  }
  fclose(fp);

  /* is this file already queued? */
  if (queue_findfile(queue_list, path) != NULL)
    return 2;

  /* allocate a queue_node */
  if ((queue_node = xmalloc(sizeof (queue_node_t))) == NULL)
    return 4;

  /* populate queue_node */
  list_lock(queue_list);
  queue_node->queue_time = time(NULL);
  queue_node->queue_status = status;
  queue_node->dispatch_time = 0;
  queue_node->dispatch_tp = NULL;
  queue_node->db_id = -1;

  /* parse nzb-file */ 
  queue_node->nzb = nzbparse(path);
  if (queue_node->nzb == NULL) {
    /* parse failed */
    list_unlock(queue_list);
    free(queue_node);
    DEBUG(2, "Failed to parse `%s', nzbparse() returned NULL", path);
    INFO(2, "Failed to queue file `%s': nzb parse error", path);
    return 5;
  }

  /* kill parsed data if preparse is disabled */    
  if (global_opts.nzb_preparse != TRUE) {
    nzb_killer(queue_node->nzb);
    queue_node->nzb->files = NULL;
  }

  /* add to sqlite3 db, queue tabel */

  if (options != QADD_IGNORE_DB) {

    db_id = sqw_queue_add(path, queue_node->queue_status);
    if (db_id == -1) {
      /* add to sql failed, probably duplicate entry, remove this nzb from queue list */
      list_unlock(queue_list);
      free(queue_node);
      INFO(2, "Failed to queue `%s', database rejection - duplicate entry?", path);
      return 6;
    }

    queue_node->db_id = db_id;
  }

  /* push queue_node to list */
  list_push(queue_list, queue_node);
  list_unlock(queue_list);


  return 0;
}
Beispiel #19
0
void* queue_mgr(void *arg)
{
  pthread_t             *my_id;

  list_t                *queue_list;
  node_t                *node;

  queue_node_t          *queue_node;

  int                   new_entries;

  int                   jobs_downloading;
  int                   jobs_waiting;
  int                   jobs_starting;
  int                   jobs_finished;

  int                   did_close_connections = 1;

  my_id = arg;

  queue_list = list_create();

  /* load queue state from db */
  sqw_queue_repopulate(queue_list);

  for (;;) {
    new_entries = queue_scan_dir(queue_list, global_opts.nzb_queuedir_drop);

    jobs_waiting = queue_count_status(queue_list, QSTAT_WAITING);
    jobs_starting = queue_count_status(queue_list, QSTAT_STARTING);
    jobs_downloading = queue_count_status(queue_list, QSTAT_DOWNLOADING);
    jobs_finished = queue_count_status(queue_list, QSTAT_FINISHED);

    if (new_entries > 0) {
        msg_send_to_type((int)my_id, TT_UI_MGR, NZB_STATUS,
            (void *)queue_list, NULL, 1);
        DEBUG(1, "added %d new entries to queue; %d waiting, %d downloading",
            new_entries, jobs_waiting, jobs_downloading);
    }


    //XXX: for profiling
    if (jobs_waiting + jobs_starting + jobs_downloading == 0) {
        if (global_opts.nntp_logoff_when_idle == TRUE && !did_close_connections) {
            did_close_connections = 1;
            free_all_connections();
        }
        else if (!global_opts.nntp_logoff_when_idle)
            clean_shutdown();
    }
    else
      did_close_connections = 0;

    if ((jobs_downloading + jobs_starting < global_opts.max_jobs) && jobs_waiting > 0) {
      list_lock(queue_list);

      node = queue_list->head;

      for (;;) {
        queue_node = node->data;
        if (queue_node->queue_status == QSTAT_WAITING) {
          DEBUG(3, "sending NZB_START_DL request to TT_DL_MGR for queue_node %p", queue_node);
          msg_send_to_type((int)my_id, TT_DL_MGR, NZB_START_DL, queue_node, NULL, 1);
          list_unlock(queue_list);
          break;
        }

        if ((node = node->next) == NULL) {
          list_unlock(queue_list);
          break;
        }

      } /* for */

    } /* send NZB_START_DL request to download mgr*/


    //printf("queue_mgr()\n");
    sleep(3);
  }


  return NULL;
}
void 
wombatThrottle_unlock (wombatThrottle throttle)
{
    list_unlock (self->mMsgQueue);
}
mama_status
wombatThrottle_dispatch (wombatThrottle throttle, 
                         void *owner, 
                         throttleCb actionCb, 
                         void *closure1, 
                         void *closure2,
                         int immediate,
                         wombatThrottleAction *handle)
{
    MsgProperties* info = NULL;
    
    if (self->mRate <= 0.0)
    {
        /* throttle is not in use, execute immediately */
        mama_log (MAMA_LOG_LEVEL_FINEST, "wombatThrottle_dispatch (): "
                  "no throttle; triggering action.");
        actionCb (closure1, closure2);
    }
    else
    {
        list_lock (self->mMsgQueue);
         info = (MsgProperties*)list_allocate_element (self->mMsgQueue);

        /* Acquire the lock before creating the timer. */
        wlock_lock (self->mTimerLock);

        /* Create the timer. */
        if (self->mTimer == NULL)
        {
            mamaTimer_create (&self->mTimer, 
                              self->mQueue,
                              wombatThrottle_timerCB,
                              self->mInterval,
                              self);

            mama_log (MAMA_LOG_LEVEL_FINEST,
                      "wombatThrottle_dispatch (): "
                      "creating throttle timer (%p).", self->mTimer);
        }

        /* Release the lock. */
        wlock_unlock (self->mTimerLock);

        if (info == NULL)
        {
            list_unlock (self->mMsgQueue);
            return (MAMA_STATUS_NOMEM);
        }

        info->mOwner = owner;
        info->mActionCb = actionCb;
        info->mClosure1 = closure1;
        info->mClosure2 = closure2;
        if (handle != NULL)
        {
            *handle = (wombatThrottleAction)info;
        }

        if (immediate)
        {
            list_push_front (self->mMsgQueue, info);
        }
        else
        {
            list_push_back (self->mMsgQueue, info);
        }
        list_unlock (self->mMsgQueue);
    }

    return MAMA_STATUS_OK;
}
Beispiel #22
0
static ssize_t data_format_t_convert_from(data_t *dst, fastcall_convert_from *fargs){ // {{{
	uintmax_t              i                       = 1;
	char                   c;
	char                   buffer[DEF_BUFFER_SIZE] = { 0 };
	char                  *p                       = buffer;
	keypair_t             *kp;
	format_t               key_val                 = 0;
	
	if(fargs->src == NULL)
		return -EINVAL;
	
	if(dst->ptr == NULL){ // no buffer, alloc new
		if( (dst->ptr = malloc(sizeof(format_t))) == NULL)
			return -ENOMEM;
	}
	
	switch(fargs->format){
		case FORMAT(config):;
		case FORMAT(human):;
			fastcall_read r_read = { { 5, ACTION_READ }, 0, &buffer, sizeof(buffer) - 1 };
			if(data_query(fargs->src, &r_read) != 0)
				return -EFAULT;
			
			while((c = *p++)){
				key_val += c * i * i;
				i++;
			}
	
	#ifdef COLLISION_CHECK
		#ifdef STATIC_KEYS_CHECK
			// find collisions
			for(kp = &formats[0]; kp->key_str != NULL; kp++){
				if(kp->key_val == key_val && strcmp(kp->key_str, buffer) != 0)
					goto collision;
			}
		#endif
		#ifdef DYNAMIC_KEYS_CHECK
			void                  *iter              = NULL;
			
			list_rdlock(&dynamic_formats);
			while( (kp = list_iter_next(&dynamic_formats, &iter)) != NULL){
				if(kp->key_val == key_val && strcmp(kp->key_str, buffer) != 0){
					list_unlock(&dynamic_formats);
					goto collision;
				}
			}
			list_unlock(&dynamic_formats);
		#endif
	#endif
		#if defined DYNAMIC_KEYS_CHECK || defined RESOLVE_DYNAMIC_KEYS
			keypair_t             *newkey            = malloc(sizeof(keypair_t));
			
			newkey->key_str = strdup(buffer);
			newkey->key_val = key_val;
			list_add(&dynamic_formats, newkey);
		#endif
	
			*(format_t *)(dst->ptr) = key_val;
			return 0;
		
		default:
			break;
	}
	return -ENOSYS;
	goto collision; // dummy

collision:
	// report collision
	fprintf(stderr, "format collision: %s <=> %s\n", kp->key_str, buffer);
	return error("format collision");
} // }}}