diff options
author | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2011-12-07 19:06:41 +0300 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2011-12-07 19:06:41 +0300 |
commit | 46ceb4ad592937ac210d1fcdfe5ee0f53d317b39 (patch) | |
tree | 229575849706886df9da026885bee94c9392c8eb /src/worker.c | |
parent | 8f1675ae06e1aa919d92fdabdc4e0d4e19c24d50 (diff) | |
download | rspamd-46ceb4ad592937ac210d1fcdfe5ee0f53d317b39.tar.gz rspamd-46ceb4ad592937ac210d1fcdfe5ee0f53d317b39.zip |
Reorganize util.c as it should contain only common utilities.
Libkvstorage client is now deprecated as I plan to replace it with hiredis library.
Diffstat (limited to 'src/worker.c')
-rw-r--r-- | src/worker.c | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/src/worker.c b/src/worker.c index d1aeea859..24cb0dd69 100644 --- a/src/worker.c +++ b/src/worker.c @@ -98,6 +98,8 @@ static gboolean write_socket (void *arg); static sig_atomic_t wanna_die = 0; +rspamd_hash_t *counters = NULL; + #ifndef HAVE_SA_SIGINFO static void sig_handler (gint signo) @@ -160,6 +162,172 @@ sigusr1_handler (gint fd, short what, void *arg) return; } +/* + * Destructor for recipients list in a task + */ +static void +rcpt_destruct (void *pointer) +{ + struct worker_task *task = (struct worker_task *) pointer; + + if (task->rcpt) { + g_list_free (task->rcpt); + } +} + +/* + * Create new task + */ +struct worker_task * +construct_task (struct rspamd_worker *worker) +{ + struct worker_task *new_task; + + new_task = g_slice_alloc0 (sizeof (struct worker_task)); + + new_task->worker = worker; + new_task->state = READ_COMMAND; + new_task->cfg = worker->srv->cfg; + new_task->from_addr.s_addr = INADDR_NONE; + new_task->view_checked = FALSE; +#ifdef HAVE_CLOCK_GETTIME +# ifdef HAVE_CLOCK_PROCESS_CPUTIME_ID + clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &new_task->ts); +# elif defined(HAVE_CLOCK_VIRTUAL) + clock_gettime (CLOCK_VIRTUAL, &new_task->ts); +# else + clock_gettime (CLOCK_REALTIME, &new_task->ts); +# endif +#endif + if (gettimeofday (&new_task->tv, NULL) == -1) { + msg_warn ("gettimeofday failed: %s", strerror (errno)); + } + + new_task->task_pool = memory_pool_new (memory_pool_get_size ()); + + /* Add destructor for recipients list (it would be better to use anonymous function here */ + memory_pool_add_destructor (new_task->task_pool, + (pool_destruct_func) rcpt_destruct, new_task); + new_task->results = g_hash_table_new (g_str_hash, g_str_equal); + memory_pool_add_destructor (new_task->task_pool, + (pool_destruct_func) g_hash_table_destroy, + new_task->results); + new_task->re_cache = g_hash_table_new (g_str_hash, g_str_equal); + memory_pool_add_destructor (new_task->task_pool, + (pool_destruct_func) g_hash_table_destroy, + new_task->re_cache); + new_task->raw_headers = g_hash_table_new (rspamd_strcase_hash, rspamd_strcase_equal); + memory_pool_add_destructor (new_task->task_pool, + (pool_destruct_func) g_hash_table_destroy, + new_task->raw_headers); + new_task->emails = g_tree_new (compare_email_func); + memory_pool_add_destructor (new_task->task_pool, + (pool_destruct_func) g_tree_destroy, + new_task->emails); + new_task->urls = g_tree_new (compare_url_func); + memory_pool_add_destructor (new_task->task_pool, + (pool_destruct_func) g_tree_destroy, + new_task->urls); + new_task->s = + new_async_session (new_task->task_pool, free_task_hard, new_task); + new_task->sock = -1; + new_task->is_mime = TRUE; + + return new_task; +} + + +/* + * Free all structures of worker_task + */ +void +free_task (struct worker_task *task, gboolean is_soft) +{ + GList *part; + struct mime_part *p; + + if (task) { + debug_task ("free pointer %p", task); + while ((part = g_list_first (task->parts))) { + task->parts = g_list_remove_link (task->parts, part); + p = (struct mime_part *) part->data; + g_byte_array_free (p->content, TRUE); + g_list_free_1 (part); + } + if (task->text_parts) { + g_list_free (task->text_parts); + } + if (task->images) { + g_list_free (task->images); + } + if (task->messages) { + g_list_free (task->messages); + } + if (task->received) { + g_list_free (task->received); + } + memory_pool_delete (task->task_pool); + if (task->dispatcher) { + if (is_soft) { + /* Plan dispatcher shutdown */ + task->dispatcher->wanna_die = 1; + } + else { + rspamd_remove_dispatcher (task->dispatcher); + } + } + if (task->sock != -1) { + close (task->sock); + } + g_slice_free1 (sizeof (struct worker_task), task); + } +} + +void +free_task_hard (gpointer ud) +{ + struct worker_task *task = ud; + + free_task (task, FALSE); +} + +void +free_task_soft (gpointer ud) +{ + struct worker_task *task = ud; + + free_task (task, FALSE); +} + +double +set_counter (const gchar *name, guint32 value) +{ + struct counter_data *cd; + double alpha; + gchar *key; + + cd = rspamd_hash_lookup (counters, (gpointer) name); + + if (cd == NULL) { + cd = memory_pool_alloc_shared (counters->pool, sizeof (struct counter_data)); + cd->value = value; + cd->number = 0; + key = memory_pool_strdup_shared (counters->pool, name); + rspamd_hash_insert (counters, (gpointer) key, (gpointer) cd); + } + else { + /* Calculate new value */ + memory_pool_wlock_rwlock (counters->lock); + + alpha = 2. / (++cd->number + 1); + cd->value = cd->value * (1. - alpha) + value * alpha; + + memory_pool_wunlock_rwlock (counters->lock); + } + + return cd->value; +} + #ifndef BUILD_STATIC static void fin_custom_filters (struct worker_task *task) @@ -244,6 +412,7 @@ parse_line_custom (struct worker_task *task, f_str_t * in) } #endif + /* * Callback that is called when there is data to read in buffer */ |