1 /* dzl-macros.h
2 *
3 * Copyright (C) 2017 Christian Hergert <chergert@redhat.com>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #ifndef DZL_MACROS_H
20 #define DZL_MACROS_H
21
22 #include <glib-object.h>
23 #include <string.h>
24
25 #ifdef __linux__
26 # include <sys/types.h>
27 # include <sys/syscall.h>
28 # include <unistd.h>
29 #endif
30
31 G_BEGIN_DECLS
32
33 #if defined(_MSC_VER)
34 # define DZL_ALIGNED_BEGIN(_N) __declspec(align(_N))
35 # define DZL_ALIGNED_END(_N)
36 #else
37 # define DZL_ALIGNED_BEGIN(_N)
38 # define DZL_ALIGNED_END(_N) __attribute__((aligned(_N)))
39 #endif
40
41 /* These were upstreamed into GLib, just use them */
42 #if GLIB_CHECK_VERSION(2,56,0)
43 # define dzl_clear_weak_pointer(ptr) g_clear_weak_pointer(ptr)
44 # define dzl_set_weak_pointer(ptr,obj) g_set_weak_pointer(ptr,obj)
45 #else
46 # define dzl_clear_weak_pointer(ptr) \
47 (*(ptr) ? (g_object_remove_weak_pointer((GObject*)*(ptr), (gpointer*)ptr),*(ptr)=NULL,1) : 0)
48 # define dzl_set_weak_pointer(ptr,obj) \
49 ((obj!=*(ptr))?(dzl_clear_weak_pointer(ptr),*(ptr)=obj,((obj)?g_object_add_weak_pointer((GObject*)obj,(gpointer*)ptr),NULL:NULL),1):0)
50 #endif
51
52 /* A more type-correct form of g_clear_pointer(), to help find bugs.
53 * GLib ended up with a similar feature which we can rely on now.
54 */
55 #if GLIB_CHECK_VERSION(2,57,2)
56 # define dzl_clear_pointer g_clear_pointer
57 #else
58 # define dzl_clear_pointer(pptr, free_func) \
59 G_STMT_START { \
60 G_STATIC_ASSERT (sizeof (*(pptr)) == sizeof (gpointer)); \
61 typeof(*(pptr)) _dzl_tmp_clear = *(pptr); \
62 *(pptr) = NULL; \
63 if (_dzl_tmp_clear) \
64 free_func (_dzl_tmp_clear); \
65 } G_STMT_END
66 #endif
67
68 /* strlen() gets hoisted out automatically at -O0 for everything but MSVC */
69 #define DZL_LITERAL_LENGTH(s) (strlen(s))
70
71 static inline void
dzl_clear_signal_handler(gpointer object,gulong * location_of_handler)72 dzl_clear_signal_handler (gpointer object,
73 gulong *location_of_handler)
74 {
75 if (*location_of_handler != 0)
76 {
77 gulong handler = *location_of_handler;
78 *location_of_handler = 0;
79 g_signal_handler_disconnect (object, handler);
80 }
81 }
82
83 static inline gboolean
dzl_str_empty0(gconstpointer str)84 dzl_str_empty0 (gconstpointer str)
85 {
86 /* We use a gconstpointer to allow passing both
87 * signed and unsigned chars into this function */
88 return str == NULL || *(char*)str == '\0';
89 }
90
91 static inline gboolean
dzl_str_equal0(gconstpointer str1,gconstpointer str2)92 dzl_str_equal0 (gconstpointer str1,
93 gconstpointer str2)
94 {
95 /* We use gconstpointer so that we can allow
96 * both signed and unsigned chars here (such as xmlChar). */
97 return g_strcmp0 ((const gchar *)str1, (const gchar *)str2) == 0;
98 }
99
100 static inline void
dzl_clear_source(guint * source_ptr)101 dzl_clear_source (guint *source_ptr)
102 {
103 guint source = *source_ptr;
104 *source_ptr = 0;
105 if (source != 0)
106 g_source_remove (source);
107 }
108
109 static inline void
dzl_assert_is_main_thread(void)110 dzl_assert_is_main_thread (void)
111 {
112 #ifndef G_DISABLE_ASSERT
113 # ifdef __linux__
114 static GThread *main_thread;
115 GThread *self = g_thread_self ();
116
117 if G_LIKELY (main_thread == self)
118 return;
119
120 /* Slow path, rely on task id == process id */
121 if ((pid_t)syscall (SYS_gettid) == getpid ())
122 {
123 /* Allow for fast path next time */
124 main_thread = self;
125 return;
126 }
127
128 g_assert_not_reached ();
129 # endif
130 #endif
131 }
132
133 G_END_DECLS
134
135 #endif /* DZL_MACROS_H */
136