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; }
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; }
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; }
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; } // }}}
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); }
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; }
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); }
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; }
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; }
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; }
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; } }
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); }
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); }
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"); } }
/* * 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); }
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; }
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; }
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"); } // }}}