2002-12-15 Havoc Pennington <hp@pobox.com>
[platform/upstream/dbus.git] / dbus / dbus-threads.c
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 1.2
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 #include "dbus-threads.h"
24 #include "dbus-internals.h"
25
26 static DBusThreadFunctions thread_functions =
27 {
28   0,
29   NULL, NULL, NULL, NULL,
30
31   NULL, NULL, NULL, NULL,
32   NULL, NULL, NULL, NULL
33 };
34
35 /**
36  * @defgroup DBusThreads Thread functions
37  * @ingroup  DBus
38  * @brief dbus_threads_init(), dbus_mutex_lock(), etc.
39  *
40  * Functions and macros related to threads and thread locks.
41  *
42  * @{
43  */
44
45 /**
46  * Creates a new mutex using the function supplied to dbus_threads_init(),
47  * or creates a no-op mutex if threads are not initialized.
48  * May return #NULL even if threads are initialized, indicating
49  * out-of-memory.
50  *
51  * @returns new mutex or #NULL
52  */
53 DBusMutex*
54 dbus_mutex_new (void)
55 {
56   if (thread_functions.mutex_new)
57     return (* thread_functions.mutex_new) ();
58   else
59     return NULL;
60 }
61
62 /**
63  * Frees a mutex created with dbus_mutex_new(); does
64  * nothing if passed a #NULL pointer.
65  */
66 void
67 dbus_mutex_free (DBusMutex *mutex)
68 {
69   if (mutex && thread_functions.mutex_free)
70     (* thread_functions.mutex_free) (mutex);
71 }
72
73 /**
74  * Locks a mutex. Does nothing if passed a #NULL pointer.
75  * Locks are not recursive.
76  *
77  * @returns #TRUE on success
78  */
79 dbus_bool_t
80 dbus_mutex_lock (DBusMutex *mutex)
81 {
82   if (mutex && thread_functions.mutex_lock)
83     return (* thread_functions.mutex_lock) (mutex);
84   else
85     return TRUE;
86 }
87
88 /**
89  * Unlocks a mutex. Does nothing if passed a #NULL pointer.
90  *
91  * @returns #TRUE on success
92  */
93 dbus_bool_t
94 dbus_mutex_unlock (DBusMutex *mutex)
95 {
96   if (mutex && thread_functions.mutex_unlock)
97     return (* thread_functions.mutex_unlock) (mutex);
98   else
99     return TRUE;
100 }
101
102 /**
103  * Initializes threads. If this function is not called,
104  * the D-BUS library will not lock any data structures.
105  * If it is called, D-BUS will do locking, at some cost
106  * in efficiency. Note that this function must be called
107  * BEFORE using any other D-BUS functions.
108  *
109  * @param functions functions for using threads
110  */
111 void
112 dbus_threads_init (const DBusThreadFunctions *functions)
113 {
114   _dbus_assert (functions != NULL);
115
116   /* these base functions are required. Future additions to
117    * DBusThreadFunctions may be optional.
118    */
119   _dbus_assert (functions->mask & DBUS_THREAD_FUNCTIONS_NEW_MASK);
120   _dbus_assert (functions->mask & DBUS_THREAD_FUNCTIONS_FREE_MASK);
121   _dbus_assert (functions->mask & DBUS_THREAD_FUNCTIONS_LOCK_MASK);
122   _dbus_assert (functions->mask & DBUS_THREAD_FUNCTIONS_UNLOCK_MASK);
123   _dbus_assert (functions->mutex_new != NULL);
124   _dbus_assert (functions->mutex_free != NULL);
125   _dbus_assert (functions->mutex_lock != NULL);
126   _dbus_assert (functions->mutex_unlock != NULL);
127
128   /* Check that all bits in the mask actually are valid mask bits.
129    * ensures people won't write code that breaks when we add
130    * new bits.
131    */
132   _dbus_assert ((functions->mask & ~DBUS_THREAD_FUNCTIONS_ALL_MASK) == 0);
133   
134   if (thread_functions.mask != 0)
135     {
136       _dbus_warn ("dbus_threads_init() may only be called one time\n");
137       return;
138     }
139   
140   thread_functions.mutex_new = functions->mutex_new;
141   thread_functions.mutex_free = functions->mutex_free;
142   thread_functions.mutex_lock = functions->mutex_lock;
143   thread_functions.mutex_unlock = functions->mutex_unlock;
144   
145   thread_functions.mask = functions->mask;
146 }
147
148 /** @} */