williamr@2: /* -*- mode: C; c-file-style: "gnu" -*- */ williamr@2: /* dbus-threads.h D-Bus threads handling williamr@2: * williamr@2: * Copyright (C) 2002 Red Hat Inc. williamr@2: * Portion Copyright © 2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. williamr@2: * Licensed under the Academic Free License version 2.1 williamr@2: * williamr@2: * This program is free software; you can redistribute it and/or modify williamr@2: * it under the terms of the GNU General Public License as published by williamr@2: * the Free Software Foundation; either version 2 of the License, or williamr@2: * (at your option) any later version. williamr@2: * williamr@2: * This program is distributed in the hope that it will be useful, williamr@2: * but WITHOUT ANY WARRANTY; without even the implied warranty of williamr@2: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the williamr@2: * GNU General Public License for more details. williamr@2: * williamr@2: * You should have received a copy of the GNU General Public License williamr@2: * along with this program; if not, write to the Free Software williamr@2: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA williamr@2: * williamr@2: */ williamr@2: #if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) williamr@2: #error "Only can be included directly, this file may disappear or change contents." williamr@2: #endif williamr@2: williamr@2: #ifndef DBUS_THREADS_H williamr@2: #define DBUS_THREADS_H williamr@2: williamr@2: #include williamr@2: #include williamr@2: williamr@2: DBUS_BEGIN_DECLS williamr@2: williamr@2: /** williamr@2: * @addtogroup DBusThreads williamr@2: * @{ williamr@2: */ williamr@2: williamr@2: /** An opaque mutex type provided by the #DBusThreadFunctions implementation installed by dbus_threads_init(). */ williamr@2: typedef struct DBusMutex DBusMutex; williamr@2: /** An opaque condition variable type provided by the #DBusThreadFunctions implementation installed by dbus_threads_init(). */ williamr@2: typedef struct DBusCondVar DBusCondVar; williamr@2: williamr@2: /** Deprecated, provide DBusRecursiveMutexNewFunction instead. */ williamr@2: typedef DBusMutex* (* DBusMutexNewFunction) (void); williamr@2: /** Deprecated, provide DBusRecursiveMutexFreeFunction instead. */ williamr@2: typedef void (* DBusMutexFreeFunction) (DBusMutex *mutex); williamr@2: /** Deprecated, provide DBusRecursiveMutexLockFunction instead. Return value is lock success, but gets ignored in practice. */ williamr@2: typedef dbus_bool_t (* DBusMutexLockFunction) (DBusMutex *mutex); williamr@2: /** Deprecated, provide DBusRecursiveMutexUnlockFunction instead. Return value is unlock success, but gets ignored in practice. */ williamr@2: typedef dbus_bool_t (* DBusMutexUnlockFunction) (DBusMutex *mutex); williamr@2: williamr@2: /** Creates a new recursively-lockable mutex, or returns #NULL if not williamr@2: * enough memory. Can only fail due to lack of memory. Found in williamr@2: * #DBusThreadFunctions. Do not just use PTHREAD_MUTEX_RECURSIVE for williamr@2: * this, because it does not save/restore the recursion count when williamr@2: * waiting on a condition. libdbus requires the Java-style behavior williamr@2: * where the mutex is fully unlocked to wait on a condition. williamr@2: */ williamr@2: typedef DBusMutex* (* DBusRecursiveMutexNewFunction) (void); williamr@2: /** Frees a recursively-lockable mutex. Found in #DBusThreadFunctions. williamr@2: */ williamr@2: typedef void (* DBusRecursiveMutexFreeFunction) (DBusMutex *mutex); williamr@2: /** Locks a recursively-lockable mutex. Found in #DBusThreadFunctions. williamr@2: * Can only fail due to lack of memory. williamr@2: */ williamr@2: typedef void (* DBusRecursiveMutexLockFunction) (DBusMutex *mutex); williamr@2: /** Unlocks a recursively-lockable mutex. Found in #DBusThreadFunctions. williamr@2: * Can only fail due to lack of memory. williamr@2: */ williamr@2: typedef void (* DBusRecursiveMutexUnlockFunction) (DBusMutex *mutex); williamr@2: williamr@2: /** Creates a new condition variable. Found in #DBusThreadFunctions. williamr@2: * Can only fail (returning #NULL) due to lack of memory. williamr@2: */ williamr@2: typedef DBusCondVar* (* DBusCondVarNewFunction) (void); williamr@2: /** Frees a condition variable. Found in #DBusThreadFunctions. williamr@2: */ williamr@2: typedef void (* DBusCondVarFreeFunction) (DBusCondVar *cond); williamr@2: williamr@2: /** Waits on a condition variable. Found in williamr@2: * #DBusThreadFunctions. Must work with either a recursive or williamr@2: * nonrecursive mutex, whichever the thread implementation williamr@2: * provides. Note that PTHREAD_MUTEX_RECURSIVE does not work with williamr@2: * condition variables (does not save/restore the recursion count) so williamr@2: * don't try using simply pthread_cond_wait() and a williamr@2: * PTHREAD_MUTEX_RECURSIVE to implement this, it won't work right. williamr@2: * williamr@2: * Has no error conditions. Must succeed if it returns. williamr@2: */ williamr@2: typedef void (* DBusCondVarWaitFunction) (DBusCondVar *cond, williamr@2: DBusMutex *mutex); williamr@2: williamr@2: /** Waits on a condition variable with a timeout. Found in williamr@2: * #DBusThreadFunctions. Returns #TRUE if the wait did not williamr@2: * time out, and #FALSE if it did. williamr@2: * williamr@2: * Has no error conditions. Must succeed if it returns. williamr@2: */ williamr@2: typedef dbus_bool_t (* DBusCondVarWaitTimeoutFunction) (DBusCondVar *cond, williamr@2: DBusMutex *mutex, williamr@2: int timeout_milliseconds); williamr@2: /** Wakes one waiting thread on a condition variable. Found in #DBusThreadFunctions. williamr@2: * williamr@2: * Has no error conditions. Must succeed if it returns. williamr@2: */ williamr@2: typedef void (* DBusCondVarWakeOneFunction) (DBusCondVar *cond); williamr@2: williamr@2: /** Wakes all waiting threads on a condition variable. Found in #DBusThreadFunctions. williamr@2: * williamr@2: * Has no error conditions. Must succeed if it returns. williamr@2: */ williamr@2: typedef void (* DBusCondVarWakeAllFunction) (DBusCondVar *cond); williamr@2: williamr@2: /** williamr@2: * Flags indicating which functions are present in #DBusThreadFunctions. Used to allow williamr@2: * the library to detect older callers of dbus_threads_init() if new possible functions williamr@2: * are added to #DBusThreadFunctions. williamr@2: */ williamr@2: typedef enum williamr@2: { williamr@2: DBUS_THREAD_FUNCTIONS_MUTEX_NEW_MASK = 1 << 0, williamr@2: DBUS_THREAD_FUNCTIONS_MUTEX_FREE_MASK = 1 << 1, williamr@2: DBUS_THREAD_FUNCTIONS_MUTEX_LOCK_MASK = 1 << 2, williamr@2: DBUS_THREAD_FUNCTIONS_MUTEX_UNLOCK_MASK = 1 << 3, williamr@2: DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK = 1 << 4, williamr@2: DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK = 1 << 5, williamr@2: DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK = 1 << 6, williamr@2: DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK = 1 << 7, williamr@2: DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK = 1 << 8, williamr@2: DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK = 1 << 9, williamr@2: DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_NEW_MASK = 1 << 10, williamr@2: DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_FREE_MASK = 1 << 11, williamr@2: DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_LOCK_MASK = 1 << 12, williamr@2: DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_UNLOCK_MASK = 1 << 13, williamr@2: DBUS_THREAD_FUNCTIONS_ALL_MASK = (1 << 14) - 1 williamr@2: } DBusThreadFunctionsMask; williamr@2: williamr@2: /** williamr@2: * Functions that must be implemented to make the D-Bus library williamr@2: * thread-aware. The recursive mutex functions should be specified williamr@2: * rather than the old, deprecated nonrecursive ones. williamr@2: * williamr@2: * The condition variable functions have to work with recursive williamr@2: * mutexes if you provide those, or with nonrecursive mutexes if you williamr@2: * provide those. williamr@2: * williamr@2: * If implementing threads using pthreads, be aware that williamr@2: * PTHREAD_MUTEX_RECURSIVE is broken in combination with condition williamr@2: * variables. libdbus relies on the Java-style behavior that when williamr@2: * waiting on a condition, the recursion count is saved and restored, williamr@2: * and the mutex is completely unlocked, not just decremented one williamr@2: * level of recursion. williamr@2: * williamr@2: * Thus with pthreads you probably have to roll your own emulated williamr@2: * recursive mutexes, you can't use PTHREAD_MUTEX_RECURSIVE. This is williamr@2: * what dbus_threads_init_default() does on platforms that use williamr@2: * pthreads. williamr@2: */ williamr@2: typedef struct williamr@2: { williamr@2: unsigned int mask; /**< Mask indicating which functions are present. */ williamr@2: williamr@2: DBusMutexNewFunction mutex_new; /**< Function to create a mutex; optional and deprecated. */ williamr@2: DBusMutexFreeFunction mutex_free; /**< Function to free a mutex; optional and deprecated. */ williamr@2: DBusMutexLockFunction mutex_lock; /**< Function to lock a mutex; optional and deprecated. */ williamr@2: DBusMutexUnlockFunction mutex_unlock; /**< Function to unlock a mutex; optional and deprecated. */ williamr@2: williamr@2: DBusCondVarNewFunction condvar_new; /**< Function to create a condition variable */ williamr@2: DBusCondVarFreeFunction condvar_free; /**< Function to free a condition variable */ williamr@2: DBusCondVarWaitFunction condvar_wait; /**< Function to wait on a condition */ williamr@2: DBusCondVarWaitTimeoutFunction condvar_wait_timeout; /**< Function to wait on a condition with a timeout */ williamr@2: DBusCondVarWakeOneFunction condvar_wake_one; /**< Function to wake one thread waiting on the condition */ williamr@2: DBusCondVarWakeAllFunction condvar_wake_all; /**< Function to wake all threads waiting on the condition */ williamr@2: williamr@2: DBusRecursiveMutexNewFunction recursive_mutex_new; /**< Function to create a recursive mutex */ williamr@2: DBusRecursiveMutexFreeFunction recursive_mutex_free; /**< Function to free a recursive mutex */ williamr@2: DBusRecursiveMutexLockFunction recursive_mutex_lock; /**< Function to lock a recursive mutex */ williamr@2: DBusRecursiveMutexUnlockFunction recursive_mutex_unlock; /**< Function to unlock a recursive mutex */ williamr@2: williamr@2: void (* padding1) (void); /**< Reserved for future expansion */ williamr@2: void (* padding2) (void); /**< Reserved for future expansion */ williamr@2: void (* padding3) (void); /**< Reserved for future expansion */ williamr@2: void (* padding4) (void); /**< Reserved for future expansion */ williamr@2: williamr@2: } DBusThreadFunctions; williamr@2: williamr@2: #ifdef __SYMBIAN32__ williamr@2: IMPORT_C williamr@2: #endif williamr@2: dbus_bool_t dbus_threads_init (const DBusThreadFunctions *functions); williamr@2: #ifdef __SYMBIAN32__ williamr@2: IMPORT_C williamr@2: #endif williamr@2: dbus_bool_t dbus_threads_init_default (void); williamr@2: williamr@2: /** @} */ williamr@2: williamr@2: DBUS_END_DECLS williamr@2: williamr@2: #endif /* DBUS_THREADS_H */