@@ -247,18 +247,20 @@ fd_funkier_rec_publish( fd_funkier_rec_prepare_t * prepare ) {
247
247
FD_COMPILER_MFENCE (); /* TODO: maybe not necessary */
248
248
}
249
249
250
+ /* We need to hold the pool lock whilst inserting and removing from the map, to make the updates
251
+ to the prev_idx/next_idx pointers atomic. */
250
252
fd_funkier_rec_pool_lock ( & rec_pool , 1 );
251
253
rec -> prev_idx = rec_prev_idx ;
252
254
if ( fd_funkier_rec_idx_is_null ( rec_prev_idx ) ) {
253
255
* rec_head_idx = rec_idx ;
254
256
} else {
255
257
rec_pool .ele [ rec_prev_idx ].next_idx = rec_idx ;
256
258
}
257
- fd_funkier_rec_pool_unlock ( & rec_pool );
258
259
259
260
if ( fd_funkier_rec_map_insert ( & rec_map , rec , FD_MAP_FLAG_BLOCKING ) ) {
260
261
FD_LOG_CRIT (( "fd_funkier_rec_map_insert failed" ));
261
262
}
263
+ fd_funkier_rec_pool_unlock ( & rec_pool );
262
264
}
263
265
264
266
void
@@ -328,18 +330,22 @@ fd_funkier_rec_hard_remove( fd_funkier_t * funk,
328
330
}
329
331
fd_funkier_rec_key_copy ( pair -> key , key );
330
332
333
+ fd_funkier_rec_pool_lock ( & rec_pool , 1 );
334
+
331
335
fd_funkier_rec_t * rec = NULL ;
332
336
for (;;) {
333
337
fd_funkier_rec_map_query_t rec_query [1 ];
334
338
int err = fd_funkier_rec_map_remove ( & rec_map , pair , NULL , rec_query , FD_MAP_FLAG_BLOCKING );
335
339
if ( FD_UNLIKELY ( err == FD_MAP_ERR_AGAIN ) ) continue ;
336
- if ( err == FD_MAP_ERR_KEY ) return ;
340
+ if ( err == FD_MAP_ERR_KEY ) {
341
+ fd_funkier_rec_pool_unlock ( & rec_pool );
342
+ return ;
343
+ }
337
344
if ( FD_UNLIKELY ( err != FD_MAP_SUCCESS ) ) FD_LOG_CRIT (( "map corruption" ));
338
345
rec = fd_funkier_rec_map_query_ele ( rec_query );
339
346
break ;
340
347
}
341
348
342
- fd_funkier_rec_pool_lock ( & rec_pool , 1 );
343
349
ulong prev_idx = rec -> prev_idx ;
344
350
ulong next_idx = rec -> next_idx ;
345
351
if ( txn == NULL ) {
0 commit comments