2006-10-26 Havoc Pennington <hp@redhat.com>
[platform/upstream/dbus.git] / dbus / dbus-threads.h
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-threads.h  D-Bus threads handling
3  *
4  * Copyright (C) 2002  Red Hat Inc.
5  *
6  * Licensed under the Academic Free License version 2.1
7  * 
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  * 
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  */
23 #if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
24 #error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
25 #endif
26
27 #ifndef DBUS_THREADS_H
28 #define DBUS_THREADS_H
29
30 #include <dbus/dbus-macros.h>
31 #include <dbus/dbus-types.h>
32
33 DBUS_BEGIN_DECLS
34
35 /**
36  * @addtogroup DBusThreads
37  * @{
38  */
39
40 /** An opaque mutex type provided by the #DBusThreadFunctions implementation installed by dbus_threads_init(). */
41 typedef struct DBusMutex DBusMutex;
42 /** An opaque condition variable type provided by the #DBusThreadFunctions implementation installed by dbus_threads_init(). */
43 typedef struct DBusCondVar DBusCondVar;
44
45 /** Deprecated, provide DBusRecursiveMutexNewFunction instead. */
46 typedef DBusMutex*  (* DBusMutexNewFunction)    (void);
47 /** Deprecated, provide DBusRecursiveMutexFreeFunction instead. */
48 typedef void        (* DBusMutexFreeFunction)   (DBusMutex *mutex);
49 /** Deprecated, provide DBusRecursiveMutexLockFunction instead. Return value is lock success, but gets ignored in practice. */
50 typedef dbus_bool_t (* DBusMutexLockFunction)   (DBusMutex *mutex);
51 /** Deprecated, provide DBusRecursiveMutexUnlockFunction instead. Return value is unlock success, but gets ignored in practice. */
52 typedef dbus_bool_t (* DBusMutexUnlockFunction) (DBusMutex *mutex);
53
54 /** Creates a new recursively-lockable mutex, or returns #NULL if not enough memory.
55  * Found in #DBusThreadFunctions. Do not just use PTHREAD_MUTEX_RECURSIVE for this, because
56  * it does not save/restore the recursion count when waiting on a condition. libdbus
57  * requires the Java-style behavior where the mutex is fully unlocked to wait on
58  * a condition.
59  */
60 typedef DBusMutex*  (* DBusRecursiveMutexNewFunction)    (void);
61 /** Frees a recursively-lockable mutex.  Found in #DBusThreadFunctions.
62  */
63 typedef void        (* DBusRecursiveMutexFreeFunction)   (DBusMutex *mutex);
64 /** Locks a recursively-lockable mutex.  Found in #DBusThreadFunctions.
65  */
66 typedef void        (* DBusRecursiveMutexLockFunction)   (DBusMutex *mutex);
67 /** Unlocks a recursively-lockable mutex.  Found in #DBusThreadFunctions.
68  */
69 typedef void        (* DBusRecursiveMutexUnlockFunction) (DBusMutex *mutex);
70
71 /** Creates a new condition variable.  Found in #DBusThreadFunctions.
72  */
73 typedef DBusCondVar*  (* DBusCondVarNewFunction)         (void);
74 /** Frees a condition variable.  Found in #DBusThreadFunctions.
75  */
76 typedef void          (* DBusCondVarFreeFunction)        (DBusCondVar *cond);
77
78 /** Waits on a condition variable.  Found in
79  * #DBusThreadFunctions. Must work with either a recursive or
80  * nonrecursive mutex, whichever the thread implementation
81  * provides. Note that PTHREAD_MUTEX_RECURSIVE does not work with
82  * condition variables (does not save/restore the recursion count) so
83  * don't try using simply pthread_cond_wait() and a
84  * PTHREAD_MUTEX_RECURSIVE to implement this, it won't work right.
85  */
86 typedef void          (* DBusCondVarWaitFunction)        (DBusCondVar *cond,
87                                                           DBusMutex   *mutex);
88
89 /** Waits on a condition variable with a timeout.  Found in
90  *  #DBusThreadFunctions. Returns #TRUE if the wait did not
91  *  time out, and #FALSE if it did.
92  */
93 typedef dbus_bool_t   (* DBusCondVarWaitTimeoutFunction) (DBusCondVar *cond,
94                                                           DBusMutex   *mutex,
95                                                           int          timeout_milliseconds);
96 /** Wakes one waiting thread on a condition variable.  Found in #DBusThreadFunctions.
97  */
98 typedef void          (* DBusCondVarWakeOneFunction) (DBusCondVar *cond);
99 /** Wakes all waiting threads on a condition variable.  Found in #DBusThreadFunctions.
100  */
101 typedef void          (* DBusCondVarWakeAllFunction) (DBusCondVar *cond);
102
103 /**
104  * Flags indicating which functions are present in #DBusThreadFunctions. Used to allow
105  * the library to detect older callers of dbus_threads_init() if new possible functions
106  * are added to #DBusThreadFunctions.
107  */
108 typedef enum 
109 {
110   DBUS_THREAD_FUNCTIONS_MUTEX_NEW_MASK      = 1 << 0,
111   DBUS_THREAD_FUNCTIONS_MUTEX_FREE_MASK     = 1 << 1,
112   DBUS_THREAD_FUNCTIONS_MUTEX_LOCK_MASK     = 1 << 2,
113   DBUS_THREAD_FUNCTIONS_MUTEX_UNLOCK_MASK   = 1 << 3,
114   DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK    = 1 << 4,
115   DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK   = 1 << 5,
116   DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK   = 1 << 6,
117   DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK   = 1 << 7,
118   DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK = 1 << 8,
119   DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK = 1 << 9,
120   DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_NEW_MASK    = 1 << 10,
121   DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_FREE_MASK   = 1 << 11,
122   DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_LOCK_MASK   = 1 << 12,
123   DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_UNLOCK_MASK = 1 << 13,
124   DBUS_THREAD_FUNCTIONS_ALL_MASK     = (1 << 13) - 1
125 } DBusThreadFunctionsMask;
126
127 /**
128  * Functions that must be implemented to make the D-Bus library
129  * thread-aware. The recursive mutex functions should be specified
130  * rather than the old, deprecated nonrecursive ones.
131  *
132  * The condition variable functions have to work with recursive
133  * mutexes if you provide those, or with nonrecursive mutexes if you
134  * provide those.
135  *
136  * If implementing threads using pthreads, be aware that
137  * PTHREAD_MUTEX_RECURSIVE is broken in combination with condition
138  * variables. libdbus relies on the Java-style behavior that when
139  * waiting on a condition, the recursion count is saved and restored,
140  * and the mutex is completely unlocked, not just decremented one
141  * level of recursion.
142  *
143  * Thus with pthreads you probably have to roll your own emulated
144  * recursive mutexes, you can't use PTHREAD_MUTEX_RECURSIVE. This is
145  * what dbus_threads_init_default() does on platforms that use
146  * pthreads.
147  */
148 typedef struct
149 {
150   unsigned int mask; /**< Mask indicating which functions are present. */
151
152   DBusMutexNewFunction mutex_new; /**< Function to create a mutex; optional and deprecated. */
153   DBusMutexFreeFunction mutex_free; /**< Function to free a mutex; optional and deprecated. */
154   DBusMutexLockFunction mutex_lock; /**< Function to lock a mutex; optional and deprecated. */
155   DBusMutexUnlockFunction mutex_unlock; /**< Function to unlock a mutex; optional and deprecated. */
156
157   DBusCondVarNewFunction condvar_new; /**< Function to create a condition variable */
158   DBusCondVarFreeFunction condvar_free; /**< Function to free a condition variable */
159   DBusCondVarWaitFunction condvar_wait; /**< Function to wait on a condition */
160   DBusCondVarWaitTimeoutFunction condvar_wait_timeout; /**< Function to wait on a condition with a timeout */
161   DBusCondVarWakeOneFunction condvar_wake_one; /**< Function to wake one thread waiting on the condition */
162   DBusCondVarWakeAllFunction condvar_wake_all; /**< Function to wake all threads waiting on the condition */
163  
164   DBusRecursiveMutexNewFunction recursive_mutex_new; /**< Function to create a recursive mutex */
165   DBusRecursiveMutexFreeFunction recursive_mutex_free; /**< Function to free a recursive mutex */
166   DBusRecursiveMutexLockFunction recursive_mutex_lock; /**< Function to lock a recursive mutex */
167   DBusRecursiveMutexUnlockFunction recursive_mutex_unlock; /**< Function to unlock a recursive mutex */
168
169   void (* padding1) (void); /**< Reserved for future expansion */
170   void (* padding2) (void); /**< Reserved for future expansion */
171   void (* padding3) (void); /**< Reserved for future expansion */
172   void (* padding4) (void); /**< Reserved for future expansion */
173   
174 } DBusThreadFunctions;
175
176 dbus_bool_t  dbus_threads_init         (const DBusThreadFunctions *functions);
177 dbus_bool_t  dbus_threads_init_default (void);
178
179 /** @} */
180
181 DBUS_END_DECLS
182
183 #endif /* DBUS_THREADS_H */