diff options
author | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2012-04-13 19:46:05 +0400 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2012-04-13 19:46:05 +0400 |
commit | 637d09abaceb0e3babff9fd25fa133da4c0732ae (patch) | |
tree | 5b66351754f9666a43cc681cd896e268a361bf34 | |
parent | efe165bc3d0f8b225be40bb8bd0bfebf7e972f04 (diff) | |
download | rspamd-637d09abaceb0e3babff9fd25fa133da4c0732ae.tar.gz rspamd-637d09abaceb0e3babff9fd25fa133da4c0732ae.zip |
Add portable api for locks and threads to handle Glib threads API change.
-rw-r--r-- | src/util.c | 189 | ||||
-rw-r--r-- | src/util.h | 78 |
2 files changed, 267 insertions, 0 deletions
diff --git a/src/util.c b/src/util.c index e7fe474ad..4db04c3d5 100644 --- a/src/util.c +++ b/src/util.c @@ -1367,6 +1367,195 @@ get_worker_by_type (GQuark type) return NULL; } +/** + * Create new mutex + * @return mutex or NULL + */ +inline rspamd_mutex_t* +rspamd_mutex_new () +{ + rspamd_mutex_t *new; + + new = g_malloc (sizeof (rspamd_mutex_t)); +#if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION > 30)) + g_mutex_init (&new->mtx); +#else + g_static_mutex_init (&new->mtx); +#endif + + return new; +} + +/** + * Lock mutex + * @param mtx + */ +inline void +rspamd_mutex_lock (rspamd_mutex_t *mtx) +{ +#if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION > 30)) + g_mutex_lock (&mtx->mtx); +#else + g_static_mutex_lock (&mtx->mtx); +#endif +} + +/** + * Unlock mutex + * @param mtx + */ +inline void +rspamd_mutex_unlock (rspamd_mutex_t *mtx) +{ +#if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION > 30)) + g_mutex_unlock (&mtx->mtx); +#else + g_static_mutex_unlock (&mtx->mtx); +#endif +} + +/** + * Create new rwlock + * @return + */ +rspamd_rwlock_t* +rspamd_rwlock_new () +{ + rspamd_rwlock_t *new; + + new = g_malloc (sizeof (rspamd_rwlock_t)); +#if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION > 30)) + g_rw_lock_init (&new->rwlock); +#else + g_static_rw_lock_init (&new->rwlock); +#endif + + return new; +} + +/** + * Lock rwlock for writing + * @param mtx + */ +inline void +rspamd_rwlock_writer_lock (rspamd_rwlock_t *mtx) +{ +#if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION > 30)) + g_rw_lock_writer_lock (&mtx->rwlock); +#else + g_static_rw_lock_writer_lock (&mtx->rwlock); +#endif +} + +/** + * Lock rwlock for reading + * @param mtx + */ +inline void +rspamd_rwlock_reader_lock (rspamd_rwlock_t *mtx) +{ +#if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION > 30)) + g_rw_lock_reader_lock (&mtx->rwlock); +#else + g_static_rw_lock_reader_lock (&mtx->rwlock); +#endif +} + +/** + * Unlock rwlock from writing + * @param mtx + */ +inline void +rspamd_rwlock_writer_unlock (rspamd_rwlock_t *mtx) +{ +#if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION > 30)) + g_rw_lock_writer_unlock (&mtx->rwlock); +#else + g_static_rw_lock_writer_unlock (&mtx->rwlock); +#endif +} + +/** + * Unlock rwlock from reading + * @param mtx + */ +inline void +rspamd_rwlock_reader_unlock (rspamd_rwlock_t *mtx) +{ +#if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION > 30)) + g_rw_lock_reader_unlock (&mtx->rwlock); +#else + g_static_rw_lock_reader_unlock (&mtx->rwlock); +#endif +} + + +struct rspamd_thread_data { + gchar *name; + gint id; + GThreadFunc func; + gpointer data; +}; + +static gpointer +rspamd_thread_func (gpointer ud) +{ + struct rspamd_thread_data *td = ud; + sigset_t s_mask; + + /* Ignore signals in thread */ + sigemptyset (&s_mask); + sigaddset (&s_mask, SIGTERM); + sigaddset (&s_mask, SIGINT); + sigaddset (&s_mask, SIGHUP); + sigaddset (&s_mask, SIGCHLD); + sigaddset (&s_mask, SIGUSR1); + sigaddset (&s_mask, SIGUSR2); + sigaddset (&s_mask, SIGALRM); + sigaddset (&s_mask, SIGPIPE); + + sigprocmask (SIG_BLOCK, &s_mask, NULL); + + ud = td->func (td->data); + g_free (td->name); + g_free (td); + + return ud; +} + +/** + * Create new named thread + * @param name name pattern + * @param func function to start + * @param data data to pass to function + * @param err error pointer + * @return new thread object that can be joined + */ +GThread* +rspamd_create_thread (const gchar *name, GThreadFunc func, gpointer data, GError **err) +{ + GThread *new; + struct rspamd_thread_data *td; + static gint32 id; + guint r; + + r = strlen (name); + td = g_malloc (sizeof (struct rspamd_thread_data)); + td->id = ++id; + td->name = g_malloc (r + sizeof ("4294967296")); + td->func = func; + td->data = data; + + rspamd_snprintf (td->name, r + sizeof ("4294967296"), "%s-%d", name, id); +#if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION > 30)) + new = g_thread_try_new (td->name, rspamd_thread_func, td, err); +#else + new = g_thread_create (rspamd_thread_func, td, TRUE, err); +#endif + + return new; +} + /* * vi:ts=4 diff --git a/src/util.h b/src/util.h index e520c9d2d..8db8cc878 100644 --- a/src/util.h +++ b/src/util.h @@ -227,4 +227,82 @@ gint rspamd_fallocate (gint fd, off_t offset, off_t len); */ worker_t* get_worker_by_type (GQuark type); +/** + * Utils for working with threads to be compatible with all glib versions + */ +typedef struct rspamd_mutex_s { +#if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION > 30)) + GMutex mtx; +#else + GStaticMutex mtx; +#endif +} rspamd_mutex_t; + +typedef struct rspamd_rwlock_s { +#if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION > 30)) + GRWLock rwlock; +#else + GStaticRWLock rwlock; +#endif +} rspamd_rwlock_t; + + +/** + * Create new mutex + * @return mutex or NULL + */ +rspamd_mutex_t* rspamd_mutex_new (); + +/** + * Lock mutex + * @param mtx + */ +void rspamd_mutex_lock (rspamd_mutex_t *mtx); + +/** + * Unlock mutex + * @param mtx + */ +void rspamd_mutex_unlock (rspamd_mutex_t *mtx); + +/** + * Create new rwloc + * @return + */ +rspamd_rwlock_t* rspamd_rwlock_new (); + +/** + * Lock rwlock for writing + * @param mtx + */ +void rspamd_rwlock_writer_lock (rspamd_rwlock_t *mtx); + +/** + * Lock rwlock for reading + * @param mtx + */ +void rspamd_rwlock_reader_lock (rspamd_rwlock_t *mtx); + +/** + * Unlock rwlock from writing + * @param mtx + */ +void rspamd_rwlock_writer_unlock (rspamd_rwlock_t *mtx); + +/** + * Unlock rwlock from reading + * @param mtx + */ +void rspamd_rwlock_reader_unlock (rspamd_rwlock_t *mtx); + +/** + * Create new named thread + * @param name name pattern + * @param func function to start + * @param data data to pass to function + * @param err error pointer + * @return new thread object that can be joined + */ +GThread* rspamd_create_thread (const gchar *name, GThreadFunc func, gpointer data, GError **err); + #endif |