Skip to content

Commit 3087817

Browse files
author
Ed Gamble
committed
CORE-589: In Core Crypto, Address TSAN #3
The FileService holds an RLP Coder and a file service is now called via multiple threads. Hence TSAN issues have arisen.
1 parent 2dfa99d commit 3087817

File tree

1 file changed

+36
-113
lines changed

1 file changed

+36
-113
lines changed

Diff for: ethereum/rlp/BRRlpCoder.c

+36-113
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@
1616
#include "ethereum/util/BRUtil.h"
1717
#include "BRRlpCoder.h"
1818

19-
static void
20-
rlpCoderReclaimInternal (BRRlpCoder coder) ;
21-
2219
static int
2320
rlpDecodeStringEmptyCheck (BRRlpCoder coder, BRRlpItem item);
2421

@@ -125,21 +122,8 @@ rlpCoderCreate (void) {
125122
return coder;
126123
}
127124

128-
extern void
129-
rlpCoderRelease (BRRlpCoder coder) {
130-
pthread_mutex_lock(&coder->lock);
131-
132-
// Every single Item must be returned!
133-
assert (NULL == coder->busy);
134-
rlpCoderReclaimInternal (coder);
135-
136-
pthread_mutex_unlock(&coder->lock);
137-
pthread_mutex_destroy(&coder->lock);
138-
free (coder);
139-
}
140-
141125
static void
142-
rlpCoderReclaimInternal (BRRlpCoder coder) {
126+
_rlpCoderReclaimInternal (BRRlpCoder coder) {
143127
BRRlpItem item = coder->free;
144128
while (item != NULL) {
145129
BRRlpItem next = item->next; // save 'next' before release...
@@ -153,22 +137,26 @@ rlpCoderReclaimInternal (BRRlpCoder coder) {
153137
extern void
154138
rlpCoderReclaim (BRRlpCoder coder) {
155139
pthread_mutex_lock(&coder->lock);
156-
rlpCoderReclaimInternal (coder);
140+
_rlpCoderReclaimInternal (coder);
157141
pthread_mutex_unlock(&coder->lock);
158142
}
159143

160-
extern int
161-
rlpCoderBusyCount (BRRlpCoder coder) {
162-
int count = 0;
163-
for (BRRlpItem found = coder->busy; NULL != found; found = found->next)
164-
count++;
165-
return count;
144+
extern void
145+
rlpCoderRelease (BRRlpCoder coder) {
146+
pthread_mutex_lock(&coder->lock);
147+
148+
// Every single Item must be returned!
149+
assert (NULL == coder->busy);
150+
_rlpCoderReclaimInternal (coder);
151+
152+
pthread_mutex_unlock(&coder->lock);
153+
pthread_mutex_destroy(&coder->lock);
154+
free (coder);
166155
}
167156

168157
static BRRlpItem
169-
rlpCoderAcquireItem (BRRlpCoder coder) {
158+
_rlpCoderAcquireItemInternal (BRRlpCoder coder) {
170159
BRRlpItem item = NULL;
171-
pthread_mutex_lock(&coder->lock);
172160

173161
// Get `item` from `coder->free` or `calloc`
174162
if (NULL != coder->free) {
@@ -188,13 +176,19 @@ rlpCoderAcquireItem (BRRlpCoder coder) {
188176
// Update `coder` to show `item` as busy.
189177
coder->busy = item;
190178

179+
return item;
180+
}
181+
182+
static BRRlpItem
183+
rlpCoderAcquireItem (BRRlpCoder coder) {
184+
pthread_mutex_lock(&coder->lock);
185+
BRRlpItem item = _rlpCoderAcquireItemInternal (coder);
191186
pthread_mutex_unlock(&coder->lock);
192187
return item;
193188
}
194189

195190
static void
196-
rlpCoderReturnItem (BRRlpCoder coder, BRRlpItem prev, BRRlpItem item, BRRlpItem next) {
197-
pthread_mutex_lock(&coder->lock);
191+
_rlpCoderReturnItemInternal (BRRlpCoder coder, BRRlpItem prev, BRRlpItem item, BRRlpItem next) {
198192
assert (NULL == item->next && NULL == item->prev &&
199193
0 == item->bytesCount && 0 == item->itemsCount);
200194

@@ -215,17 +209,26 @@ rlpCoderReturnItem (BRRlpCoder coder, BRRlpItem prev, BRRlpItem item, BRRlpItem
215209

216210
// Update `coder` to show `item` as free.
217211
coder->free = item;
218-
219-
pthread_mutex_unlock(&coder->lock);
220212
}
221213

222214
static void
223-
itemRelease (BRRlpCoder coder, BRRlpItem item) {
215+
_rlpCoderReleaseItemInternal (BRRlpCoder coder, BRRlpItem item) {
216+
for (size_t index = 0; index < item->itemsCount; index++)
217+
_rlpCoderReleaseItemInternal (coder, item->items[index]);
218+
219+
// Surely get these before itemReleaseMemory() blows them away.
224220
BRRlpItem prev = item->prev;
225221
BRRlpItem next = item->next;
226222

227223
itemReleaseMemory(item);
228-
rlpCoderReturnItem(coder, prev, item, next);
224+
_rlpCoderReturnItemInternal (coder, prev, item, next);
225+
}
226+
227+
static void
228+
rlpCoderReleaseItem (BRRlpCoder coder, BRRlpItem item) {
229+
pthread_mutex_lock(&coder->lock);
230+
_rlpCoderReleaseItemInternal (coder, item);
231+
pthread_mutex_unlock(&coder->lock);
229232
}
230233

231234
static int
@@ -277,84 +280,6 @@ rlpCoderHasFailed (BRRlpCoder coder) {
277280
return coder->failed;
278281
}
279282

280-
#if 0
281-
static BRRlpItem
282-
itemCreate (BRRlpCoder coder,
283-
uint8_t *bytes, size_t bytesCount, int takeBytes) {
284-
BRRlpItem item = calloc (1, sizeof (struct BRRlpItemRecord));
285-
286-
item->type = CODER_ITEM;
287-
item->bytesCount = bytesCount;
288-
if (takeBytes)
289-
item->bytes = bytes;
290-
else {
291-
item->bytes = (item->bytesCount > ITEM_DEFAULT_BYTES_COUNT
292-
? malloc (item->bytesCount)
293-
: item->bytesArray);
294-
memcpy (item->bytes, bytes, item->bytesCount);
295-
}
296-
item->itemsCount = 0;
297-
item->items = NULL;
298-
299-
return item;
300-
}
301-
302-
static BRRlpItem
303-
itemCreateList (BRRlpCoder coder,
304-
uint8_t *bytes, size_t bytesCount, int takeBytes,
305-
BRRlpItem *items, size_t itemsCount) {
306-
BRRlpItem item = itemCreate(coder, bytes, bytesCount, takeBytes);
307-
item->type = CODER_LIST;
308-
item->itemsCount = itemsCount;
309-
item->items = (item->itemsCount > ITEM_DEFAULT_ITEMS_COUNT
310-
? calloc (item->itemsCount, sizeof (BRRlpItem))
311-
: item->itemsArray);
312-
for (int i = 0; i < itemsCount; i++)
313-
item->items[i] = items[i];
314-
315-
return item;
316-
}
317-
#endif
318-
319-
/**
320-
* Return a new BRRlpContext by appending the two provided contexts. Both provided contexts
321-
* must be for CODER_ITEM (othewise an 'assert' is raised); the appending is performed by simply
322-
* concatenating the two context's byte arrays.
323-
*
324-
* If release is TRUE, then both the provided contexts are released; thereby freeing their memory.
325-
*
326-
*/
327-
#if 0
328-
static BRRlpItem
329-
itemCreateAppend (BRRlpCoder coder, BRRlpItem context1, BRRlpItem context2, int release) {
330-
assert (CODER_ITEM == context1->type && CODER_ITEM == context2->type);
331-
332-
BRRlpItem item = calloc (1, sizeof (struct BRRlpItemRecord));
333-
334-
item->type = CODER_ITEM;
335-
336-
item->bytesCount = context1->bytesCount + context2->bytesCount;
337-
item->bytes = (item->bytesCount > ITEM_DEFAULT_BYTES_COUNT
338-
? malloc (item->bytesCount)
339-
: item->bytesArray);
340-
341-
memcpy (&item->bytes[0], context1->bytes, context1->bytesCount);
342-
memcpy (&item->bytes[context1->bytesCount], context2->bytes, context2->bytesCount);
343-
344-
item->itemsCount = 0;
345-
item->items = NULL;
346-
347-
if (release) {
348-
// assert (context2.bytes != context1.bytes || context2.bytes == NULL || context1.bytes == NULL);
349-
// assert (context2.items != context1.items || context2.items == NULL || context1.items == NULL);
350-
itemRelease(coder, context1);
351-
itemRelease(coder, context2);
352-
}
353-
354-
return item;
355-
}
356-
#endif
357-
358283
// The largest number supported for encoding is a UInt256 - which is representable as 32 bytes.
359284
#define CODER_NUMBER_BYTES_LIMIT (256/8)
360285

@@ -1071,9 +996,7 @@ rlpShowItemInternal (BRRlpCoder coder, BRRlpItem context, const char *topic, int
1071996
extern void
1072997
rlpReleaseItem (BRRlpCoder coder, BRRlpItem item) {
1073998
assert (itemIsValid(coder, item));
1074-
for (size_t index = 0; index < item->itemsCount; index++)
1075-
rlpReleaseItem(coder, item->items[index]);
1076-
itemRelease(coder, item);
999+
rlpCoderReleaseItem (coder, item);
10771000
}
10781001

10791002
extern void

0 commit comments

Comments
 (0)