]> source.dussan.org Git - rspamd.git/commitdiff
Add portable api for locks and threads to handle Glib threads API change.
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Fri, 13 Apr 2012 15:46:05 +0000 (19:46 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Fri, 13 Apr 2012 15:46:05 +0000 (19:46 +0400)
src/util.c
src/util.h

index e7fe474ad1204c59692505cb227afcbf46b72c9b..4db04c3d5050768c03dd04a9f992a7be0a3769d5 100644 (file)
@@ -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
index e520c9d2d79bbe881a1feb5b4d14157a1519d835..8db8cc87883fcfc379c5c3505c137327cd46940b 100644 (file)
@@ -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