Skip to content

Commit 02fd694

Browse files
committed
CDRIVER-748 fix mock server for TSAN (#620)
mock_server_hangs_up and mock_server_resets were closing a request stream directly from the main thread. But a request stream should only be accessed by the worker thread. This now adds a special reply to the worker thread's queue to signal a hangup or reset.
1 parent 1639ca9 commit 02fd694

File tree

2 files changed

+31
-14
lines changed

2 files changed

+31
-14
lines changed

src/libmongoc/tests/mock_server/mock-server.c

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,13 @@ struct _autoresponder_handle_t {
7272
int id;
7373
};
7474

75+
typedef enum {
76+
REPLY, HANGUP, RESET
77+
} reply_type_t;
78+
7579

7680
typedef struct {
81+
reply_type_t type;
7782
mongoc_reply_flags_t flags;
7883
bson_t *docs;
7984
int n_docs;
@@ -1218,12 +1223,14 @@ mock_server_receives_kill_cursors (mock_server_t *server, int64_t cursor_id)
12181223
void
12191224
mock_server_hangs_up (request_t *request)
12201225
{
1226+
reply_t *reply;
12211227
test_suite_mock_server_log ("%5.2f %hu <- %hu \thang up!",
12221228
mock_server_get_uptime_sec (request->server),
12231229
request->client_port,
12241230
request_get_server_port (request));
1225-
1226-
mongoc_stream_close (request->client);
1231+
reply = bson_malloc0 (sizeof (reply_t));
1232+
reply->type = HANGUP;
1233+
q_put (request->replies, reply);
12271234
}
12281235

12291236

@@ -1245,20 +1252,15 @@ mock_server_hangs_up (request_t *request)
12451252
void
12461253
mock_server_resets (request_t *request)
12471254
{
1248-
struct linger no_linger;
1249-
no_linger.l_onoff = 1;
1250-
no_linger.l_linger = 0;
1251-
1255+
reply_t *reply;
12521256
test_suite_mock_server_log ("%5.2f %hu <- %hu \treset!",
12531257
mock_server_get_uptime_sec (request->server),
12541258
request->client_port,
12551259
request_get_server_port (request));
12561260

1257-
/* send RST packet to client */
1258-
mongoc_stream_setsockopt (
1259-
request->client, SOL_SOCKET, SO_LINGER, &no_linger, sizeof no_linger);
1260-
1261-
mongoc_stream_close (request->client);
1261+
reply = bson_malloc0 (sizeof (reply_t));
1262+
reply->type = RESET;
1263+
q_put (request->replies, reply);
12621264
}
12631265

12641266

@@ -1331,7 +1333,6 @@ mock_server_replies_simple (request_t *request, const char *docs_json)
13311333
mock_server_replies (request, MONGOC_REPLY_NONE, 0, 0, 1, docs_json);
13321334
}
13331335

1334-
13351336
/*--------------------------------------------------------------------------
13361337
*
13371338
* mock_server_replies_ok_and_destroys --
@@ -1801,6 +1802,7 @@ mock_server_reply_multi (request_t *request,
18011802

18021803
reply = bson_malloc0 (sizeof (reply_t));
18031804

1805+
reply->type = REPLY;
18041806
reply->flags = flags;
18051807
reply->n_docs = n_docs;
18061808
reply->docs = bson_malloc0 (n_docs * sizeof (bson_t));
@@ -1837,12 +1839,26 @@ _mock_server_reply_with_stream (mock_server_t *server,
18371839
uint8_t *ptr;
18381840
size_t len;
18391841
bool is_op_msg;
1840-
18411842
mongoc_reply_flags_t flags = reply->flags;
18421843
const bson_t *docs = reply->docs;
18431844
int n_docs = reply->n_docs;
18441845
int64_t cursor_id = reply->cursor_id;
18451846

1847+
if (reply->type == HANGUP) {
1848+
mongoc_stream_close (client);
1849+
return;
1850+
} else if (reply->type == RESET) {
1851+
struct linger no_linger;
1852+
no_linger.l_onoff = 1;
1853+
no_linger.l_linger = 0;
1854+
1855+
/* send RST packet to client */
1856+
mongoc_stream_setsockopt (client, SOL_SOCKET, SO_LINGER, &no_linger, sizeof no_linger);
1857+
1858+
mongoc_stream_close (client);
1859+
return;
1860+
}
1861+
18461862
docs_json = bson_string_new ("");
18471863
for (i = 0; i < n_docs; i++) {
18481864
doc_json = bson_as_json (&docs[i], NULL);

src/libmongoc/tests/test-libmongoc.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,13 +409,14 @@ log_handler (mongoc_log_level_t log_level,
409409
suite = (TestSuite *) user_data;
410410

411411
if (log_level < MONGOC_LOG_LEVEL_INFO) {
412+
bson_mutex_lock (&captured_logs_mutex);
412413
if (capturing_logs) {
413414
log_entry = log_entry_create (log_level, message);
414-
bson_mutex_lock (&captured_logs_mutex);
415415
_mongoc_array_append_val (&captured_logs, log_entry);
416416
bson_mutex_unlock (&captured_logs_mutex);
417417
return;
418418
}
419+
bson_mutex_unlock (&captured_logs_mutex);
419420

420421
if (!suite->silent) {
421422
mongoc_log_default_handler (log_level, log_domain, message, NULL);

0 commit comments

Comments
 (0)