summaryrefslogtreecommitdiff
path: root/dbus/dbus-threads-internal.h
blob: 4c7bde63a6ac35c02f66d171a83f781cdb4320eb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* dbus-threads-internal.h  D-Bus thread primitives
 *
 * Copyright (C) 2002, 2005 Red Hat Inc.
 *
 * SPDX-License-Identifier: AFL-2.1 OR GPL-2.0-or-later
 *
 * Licensed under the Academic Free License version 2.1
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */
#ifndef DBUS_THREADS_INTERNAL_H
#define DBUS_THREADS_INTERNAL_H

#include <dbus/dbus-macros.h>
#include <dbus/dbus-types.h>
#include <dbus/dbus-threads.h>

/**
 * @addtogroup DBusThreadsInternals
 * @{
 */

/**
 * A mutex which is recursive if possible, else non-recursive.
 * This is typically recursive, but that cannot be relied upon.
 */
typedef struct DBusRMutex DBusRMutex;

/**
 * A mutex suitable for use with condition variables.
 * This is typically non-recursive.
 */
typedef struct DBusCMutex DBusCMutex;

/** @} */

DBUS_BEGIN_DECLS

DBUS_PRIVATE_EXPORT
void         _dbus_rmutex_lock               (DBusRMutex       *mutex);
DBUS_PRIVATE_EXPORT
void         _dbus_rmutex_unlock             (DBusRMutex       *mutex);
void         _dbus_rmutex_new_at_location    (DBusRMutex      **location_p);
void         _dbus_rmutex_free_at_location   (DBusRMutex      **location_p);

void         _dbus_cmutex_lock               (DBusCMutex       *mutex);
void         _dbus_cmutex_unlock             (DBusCMutex       *mutex);
void         _dbus_cmutex_new_at_location    (DBusCMutex      **location_p);
void         _dbus_cmutex_free_at_location   (DBusCMutex      **location_p);

DBusCondVar* _dbus_condvar_new               (void);
void         _dbus_condvar_free              (DBusCondVar       *cond);
void         _dbus_condvar_wait              (DBusCondVar       *cond,
                                              DBusCMutex        *mutex);
dbus_bool_t  _dbus_condvar_wait_timeout      (DBusCondVar       *cond,
                                              DBusCMutex        *mutex,
                                              int                timeout_milliseconds);
void         _dbus_condvar_wake_one          (DBusCondVar       *cond);
void         _dbus_condvar_new_at_location   (DBusCondVar      **location_p);
void         _dbus_condvar_free_at_location  (DBusCondVar      **location_p);

/* Private to threading implementations and dbus-threads.c */

/**
 * Creates a new mutex which is recursive if possible
 *
 * This mutex is used to avoid deadlocking if we hold them while
 * calling user code.
 *
 * @return  mutex instance or #NULL on OOM
 */
DBUS_EMBEDDED_TESTS_EXPORT
DBusRMutex  *_dbus_platform_rmutex_new       (void);

/**
 * Free a recursive usable mutex
 *
 * @param mutex the mutex instance to free
 */
DBUS_EMBEDDED_TESTS_EXPORT
void         _dbus_platform_rmutex_free      (DBusRMutex       *mutex);

/**
 * Locks a recursively usable mutex
 *
 * @param mutex the mutex instance to lock
 *
 * Unlike _dbus_cmutex_lock(), it is valid for the same thread
 * to lock a recursive mutex more than once, and it will not
 * deadlock. Each call to this function must be paired with a
 * corresponding call to _dbus_rmutex_unlock().
 */
DBUS_EMBEDDED_TESTS_EXPORT
void         _dbus_platform_rmutex_lock      (DBusRMutex       *mutex);

/**
 * Release a recursively usable mutex
 *
 * @param mutex the mutex instance to release
 */
DBUS_EMBEDDED_TESTS_EXPORT
void         _dbus_platform_rmutex_unlock    (DBusRMutex       *mutex);

/**
 * Creates a new mutex suitable for use with condition variables
 *
 * @return  mutex instance or #NULL on OOM
 */
DBUS_EMBEDDED_TESTS_EXPORT
DBusCMutex  *_dbus_platform_cmutex_new       (void);

/**
 * Implementation of _dbus_rmutex_new_at_location().
 * This should only be called internally by the threading implementation.
 */
DBUS_EMBEDDED_TESTS_EXPORT
void         _dbus_platform_cmutex_free      (DBusCMutex       *mutex);

/**
 * Locks a mutex suitable for use with condition variables
 *
 * @param mutex the mutex instance to lock
 *
 * @note On Windows, after a thread obtains ownership of a mutex,
 * it can specify the same mutex in repeated calls to the dbus
 * platform related mutex lock functions without blocking its
 * execution. This prevents a thread from deadlocking itself
 * while waiting for a mutex that it already owns. On unix
 * like os, calling the dbus platform related mutex lock
 * functions the second time is a programming error.
 */
DBUS_EMBEDDED_TESTS_EXPORT
void         _dbus_platform_cmutex_lock      (DBusCMutex       *mutex);

/**
 * Release a mutex suitable for use with condition variables
 *
 * @param mutex the mutex instance to release
 */
DBUS_EMBEDDED_TESTS_EXPORT
void         _dbus_platform_cmutex_unlock    (DBusCMutex       *mutex);

DBusCondVar* _dbus_platform_condvar_new      (void);
void         _dbus_platform_condvar_free     (DBusCondVar       *cond);
void         _dbus_platform_condvar_wait     (DBusCondVar       *cond,
                                              DBusCMutex        *mutex);
dbus_bool_t  _dbus_platform_condvar_wait_timeout (DBusCondVar   *cond,
                                              DBusCMutex        *mutex,
                                              int                timeout_milliseconds);
void         _dbus_platform_condvar_wake_one (DBusCondVar       *cond);

DBUS_END_DECLS

#endif /* DBUS_THREADS_INTERNAL_H */