Skip to content

Commit 8d1af19

Browse files
CDRIVER-4227 Add a shared_mutex, and use it when locking in shared_ptr atomic operations (#895)
* Add a shared_mutex, and use it when locking in shared_ptr atomic operations Tag CDRIVER-4002 Co-authored-by: Kevin Albertson <[email protected]> * Force enable more recent POSIX APIs, regardless of language mode This change only applies to private code, and does not expose any changes in the public API. * No reallocf in strict POSIX mode Co-authored-by: Kevin Albertson <[email protected]>
1 parent 2078ab2 commit 8d1af19

File tree

5 files changed

+65
-41
lines changed

5 files changed

+65
-41
lines changed

src/common/common-thread-private.h

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ typedef struct {
105105
#define bson_once_t INIT_ONCE
106106
#define bson_thread_t HANDLE
107107
#define BSON_THREAD_FUN(_function_name, _arg_name) \
108-
unsigned(__stdcall _function_name) (void *(_arg_name))
108+
unsigned (__stdcall _function_name) (void *(_arg_name))
109109
#define BSON_THREAD_FUN_TYPE(_function_name) \
110110
unsigned (__stdcall * _function_name) (void *)
111111
#define BSON_THREAD_RETURN return 0
@@ -123,6 +123,61 @@ int COMMON_PREFIX (thread_create) (bson_thread_t *thread,
123123
bool COMMON_PREFIX (mutex_is_locked) (bson_mutex_t *mutex);
124124
#endif
125125

126+
/**
127+
* @brief A shared mutex (a read-write lock)
128+
*
129+
* A shared mutex can be locked in 'shared' mode or 'exclusive' mode. Only one
130+
* thread may hold exclusive mode at a time. Any number of threads may hold
131+
* the lock in shared mode simultaneously. No thread can hold in exclusive mode
132+
* while another thread holds in shared mode, and vice-versa.
133+
*/
134+
typedef struct bson_shared_mutex_t {
135+
BSON_IF_WINDOWS (SRWLOCK native;)
136+
BSON_IF_POSIX (pthread_rwlock_t native;)
137+
} bson_shared_mutex_t;
138+
139+
static BSON_INLINE void
140+
bson_shared_mutex_init (bson_shared_mutex_t *mtx)
141+
{
142+
BSON_IF_WINDOWS (InitializeSRWLock (&mtx->native));
143+
BSON_IF_POSIX (pthread_rwlock_init (&mtx->native, NULL));
144+
}
145+
146+
static BSON_INLINE void
147+
bson_shared_mutex_destroy (bson_shared_mutex_t *mtx)
148+
{
149+
BSON_IF_WINDOWS ((void) mtx;)
150+
BSON_IF_POSIX (pthread_rwlock_destroy (&mtx->native);)
151+
}
152+
153+
static BSON_INLINE void
154+
bson_shared_mutex_lock_shared (bson_shared_mutex_t *mtx)
155+
{
156+
BSON_IF_WINDOWS (AcquireSRWLockShared (&mtx->native);)
157+
BSON_IF_POSIX (pthread_rwlock_rdlock (&mtx->native);)
158+
}
159+
160+
static BSON_INLINE void
161+
bson_shared_mutex_lock (bson_shared_mutex_t *mtx)
162+
{
163+
BSON_IF_WINDOWS (AcquireSRWLockExclusive (&mtx->native);)
164+
BSON_IF_POSIX (pthread_rwlock_wrlock (&mtx->native);)
165+
}
166+
167+
static BSON_INLINE void
168+
bson_shared_mutex_unlock (bson_shared_mutex_t *mtx)
169+
{
170+
BSON_IF_WINDOWS (ReleaseSRWLockExclusive (&mtx->native);)
171+
BSON_IF_POSIX (pthread_rwlock_unlock (&mtx->native);)
172+
}
173+
174+
static BSON_INLINE void
175+
bson_shared_mutex_unlock_shared (bson_shared_mutex_t *mtx)
176+
{
177+
BSON_IF_WINDOWS (ReleaseSRWLockShared (&mtx->native);)
178+
BSON_IF_POSIX (pthread_rwlock_unlock (&mtx->native);)
179+
}
180+
126181
BSON_END_DECLS
127182

128183
#endif /* COMMON_THREAD_PRIVATE_H */

src/libbson/CMakeLists.txt

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ set (BSON_API_VERSION 1.0)
3333
set (CPACK_PACKAGE_VERSION_MAJOR ${BSON_MAJOR_VERSION})
3434
set (CPACK_PACKAGE_VERSION_MINOR ${BSON_MINOR_VERSION})
3535

36+
# Enable X/Open 7.0 / POSIX 2008
37+
add_compile_options($<$<NOT:$<PLATFORM_ID:Windows>>:-D_XOPEN_SOURCE=700>)
38+
3639
include (CPack)
3740
TEST_BIG_ENDIAN (BSON_BIG_ENDIAN)
3841

@@ -52,11 +55,6 @@ else ()
5255
set (BSON_HAVE_SNPRINTF 1)
5356
endif ()
5457

55-
CHECK_FUNCTION_EXISTS (reallocf BSON_HAVE_REALLOCF)
56-
if (NOT BSON_HAVE_REALLOCF)
57-
set (BSON_HAVE_REALLOCF 0)
58-
endif ()
59-
6058
CHECK_STRUCT_HAS_MEMBER ("struct timespec" tv_sec time.h BSON_HAVE_TIMESPEC)
6159
if (NOT BSON_HAVE_TIMESPEC)
6260
message (STATUS " no timespec struct")

src/libbson/src/bson/bson-config.h.in

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,6 @@
8787
#endif
8888

8989

90-
/*
91-
* Define to 1 if you have reallocf available on your platform.
92-
*/
93-
#define BSON_HAVE_REALLOCF @BSON_HAVE_REALLOCF@
94-
#if BSON_HAVE_REALLOCF != 1
95-
# undef BSON_HAVE_REALLOCF
96-
#endif
97-
98-
9990
/*
10091
* Define to 1 if you have struct timespec available on your platform.
10192
*/

src/libbson/src/bson/bson-memory.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,7 @@
2828
static bson_mem_vtable_t gMemVtable = {
2929
malloc,
3030
calloc,
31-
#ifdef BSON_HAVE_REALLOCF
32-
reallocf,
33-
#else
3431
realloc,
35-
#endif
3632
free,
3733
};
3834

@@ -299,11 +295,7 @@ bson_mem_restore_vtable (void)
299295
bson_mem_vtable_t vtable = {
300296
malloc,
301297
calloc,
302-
#ifdef BSON_HAVE_REALLOCF
303-
reallocf,
304-
#else
305298
realloc,
306-
#endif
307299
free,
308300
};
309301

src/libmongoc/src/mongoc/mongoc-shared.c

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,27 +32,15 @@ _release_aux (_mongoc_shared_ptr_aux *aux)
3232
bson_free (aux);
3333
}
3434

35-
static bson_mutex_t g_shared_ptr_mtx;
35+
static bson_shared_mutex_t g_shared_ptr_mtx;
3636
static bson_once_t g_shared_ptr_mtx_init_once = BSON_ONCE_INIT;
3737

3838
static BSON_ONCE_FUN (_init_mtx)
3939
{
40-
bson_mutex_init (&g_shared_ptr_mtx);
40+
bson_shared_mutex_init (&g_shared_ptr_mtx);
4141
BSON_ONCE_RETURN;
4242
}
4343

44-
static void
45-
_shared_ptr_lock ()
46-
{
47-
bson_mutex_lock (&g_shared_ptr_mtx);
48-
}
49-
50-
static void
51-
_shared_ptr_unlock ()
52-
{
53-
bson_mutex_unlock (&g_shared_ptr_mtx);
54-
}
55-
5644
void
5745
mongoc_shared_ptr_reset (mongoc_shared_ptr *const ptr,
5846
void *const pointee,
@@ -105,11 +93,11 @@ mongoc_atomic_shared_ptr_store (mongoc_shared_ptr *const out,
10593
/* We are effectively "copying" the 'from' */
10694
(void) mongoc_shared_ptr_copy (from);
10795

108-
_shared_ptr_lock ();
96+
bson_shared_mutex_lock (&g_shared_ptr_mtx);
10997
/* Do the exchange. Quick! */
11098
prev = *out;
11199
*out = from;
112-
_shared_ptr_unlock ();
100+
bson_shared_mutex_unlock (&g_shared_ptr_mtx);
113101

114102
/* Free the pointer that we just overwrote */
115103
mongoc_shared_ptr_reset_null (&prev);
@@ -120,9 +108,9 @@ mongoc_atomic_shared_ptr_load (mongoc_shared_ptr const *ptr)
120108
{
121109
mongoc_shared_ptr r;
122110
BSON_ASSERT_PARAM (ptr);
123-
_shared_ptr_lock ();
111+
bson_shared_mutex_lock_shared (&g_shared_ptr_mtx);
124112
r = mongoc_shared_ptr_copy (*ptr);
125-
_shared_ptr_unlock ();
113+
bson_shared_mutex_unlock_shared (&g_shared_ptr_mtx);
126114
return r;
127115
}
128116

0 commit comments

Comments
 (0)