Skip to content

Commit e363b49

Browse files
committed
Make multi add/remove/preload thread-safe
Signed-off-by: falkTX <falktx@falktx.com>
1 parent 864e926 commit e363b49

File tree

1 file changed

+52
-14
lines changed

1 file changed

+52
-14
lines changed

src/effects.c

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,9 @@ static pthread_mutex_t g_midi_learning_mutex;
844844
static bool g_monitored_midi_controls[16];
845845
static bool g_monitored_midi_programs[16];
846846

847+
/* multi-threading */
848+
static pthread_mutex_t g_multi_thread_mutex;
849+
847850
#ifdef HAVE_HYLIA
848851
static hylia_t* g_hylia_instance;
849852
static hylia_time_info_t g_hylia_timeinfo;
@@ -907,7 +910,7 @@ static property_t *FindEffectPropertyByURI(effect_t *effect, const char *uri);
907910
static port_t *FindEffectInputPortBySymbol(effect_t *effect, const char *control_symbol);
908911
static port_t *FindEffectOutputPortBySymbol(effect_t *effect, const char *control_symbol);
909912
static const void *GetPortValueForState(const char* symbol, void* user_data, uint32_t* size, uint32_t* type);
910-
static int LoadPresets(effect_t *effect);
913+
static void LoadPresets(effect_t *effect);
911914
static void FreeFeatures(effect_t *effect);
912915
static void FreePluginString(void* handle, char *str);
913916
static void ConnectToAllHardwareMIDIPorts(void);
@@ -3408,16 +3411,16 @@ static const void* GetPortValueForState(const char* symbol, void* user_data, uin
34083411
return NULL;
34093412
}
34103413

3411-
static int LoadPresets(effect_t *effect)
3414+
static void LoadPresets(effect_t *effect)
34123415
{
3416+
pthread_mutex_lock(&g_multi_thread_mutex);
3417+
34133418
LilvNodes* presets = lilv_plugin_get_related(effect->lilv_plugin, g_lilv_nodes.preset);
34143419
uint32_t presets_count = lilv_nodes_size(presets);
34153420
effect->presets_count = presets_count;
34163421
// allocate for presets
34173422
effect->presets = (preset_t **) mod_calloc(presets_count, sizeof(preset_t *));
34183423
uint32_t j = 0;
3419-
for (j = 0; j < presets_count; j++) effect->presets[j] = NULL;
3420-
j = 0;
34213424
LILV_FOREACH(nodes, i, presets)
34223425
{
34233426
const LilvNode* preset = lilv_nodes_get(presets, i);
@@ -3427,7 +3430,7 @@ static int LoadPresets(effect_t *effect)
34273430
}
34283431
lilv_nodes_free(presets);
34293432

3430-
return 0;
3433+
pthread_mutex_unlock(&g_multi_thread_mutex);
34313434
}
34323435

34333436
// ignore const cast for this function, need to free const features array
@@ -4246,6 +4249,7 @@ int effects_init(void* client)
42464249
pthread_mutex_init(&g_raw_midi_port_mutex, &mutex_atts);
42474250
pthread_mutex_init(&g_audio_monitor_mutex, &mutex_atts);
42484251
pthread_mutex_init(&g_midi_learning_mutex, &mutex_atts);
4252+
pthread_mutex_init(&g_multi_thread_mutex, &mutex_atts);
42494253
#ifdef __MOD_DEVICES__
42504254
pthread_mutex_init(&g_hmi_mutex, &mutex_atts);
42514255
#endif
@@ -4829,6 +4833,7 @@ int effects_finish(int close_client)
48294833
pthread_mutex_destroy(&g_raw_midi_port_mutex);
48304834
pthread_mutex_destroy(&g_audio_monitor_mutex);
48314835
pthread_mutex_destroy(&g_midi_learning_mutex);
4836+
pthread_mutex_destroy(&g_multi_thread_mutex);
48324837
#ifdef __MOD_DEVICES__
48334838
pthread_mutex_destroy(&g_hmi_mutex);
48344839
#endif
@@ -4913,6 +4918,8 @@ int effects_add(const char *uri, int instance, int activate)
49134918
}
49144919
effect->jack_client = jack_client;
49154920

4921+
pthread_mutex_lock(&g_multi_thread_mutex);
4922+
49164923
/* Get the plugin */
49174924
plugin_uri = lilv_new_uri(g_lv2_data, uri);
49184925
plugin = lilv_plugins_get_by_uri(g_plugins, plugin_uri);
@@ -4932,6 +4939,7 @@ int effects_add(const char *uri, int instance, int activate)
49324939
if (!plugin)
49334940
#endif
49344941
{
4942+
pthread_mutex_unlock(&g_multi_thread_mutex);
49354943
fprintf(stderr, "can't get plugin\n");
49364944
error = ERR_LV2_INVALID_URI;
49374945
goto error;
@@ -4954,6 +4962,7 @@ int effects_add(const char *uri, int instance, int activate)
49544962

49554963
if (!lilv_instance)
49564964
{
4965+
pthread_mutex_unlock(&g_multi_thread_mutex);
49574966
fprintf(stderr, "can't get lilv instance\n");
49584967
error = ERR_LV2_INSTANTIATION;
49594968
goto error;
@@ -5108,6 +5117,7 @@ int effects_add(const char *uri, int instance, int activate)
51085117
audio_buffer = (float *) mod_calloc(g_sample_rate, sizeof(float));
51095118
if (!audio_buffer)
51105119
{
5120+
pthread_mutex_unlock(&g_multi_thread_mutex);
51115121
fprintf(stderr, "can't get audio buffer\n");
51125122
error = ERR_MEMORY_ALLOCATION;
51135123
goto error;
@@ -5121,6 +5131,7 @@ int effects_add(const char *uri, int instance, int activate)
51215131
jack_port = jack_port_register(jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, jack_flags, 0);
51225132
if (jack_port == NULL)
51235133
{
5134+
pthread_mutex_unlock(&g_multi_thread_mutex);
51245135
fprintf(stderr, "can't get jack port\n");
51255136
error = ERR_JACK_PORT_REGISTER;
51265137
goto error;
@@ -5139,6 +5150,7 @@ int effects_add(const char *uri, int instance, int activate)
51395150
control_buffer = (float *) malloc(sizeof(float));
51405151
if (!control_buffer)
51415152
{
5153+
pthread_mutex_unlock(&g_multi_thread_mutex);
51425154
fprintf(stderr, "can't get control buffer\n");
51435155
error = ERR_MEMORY_ALLOCATION;
51445156
goto error;
@@ -5261,6 +5273,7 @@ int effects_add(const char *uri, int instance, int activate)
52615273
cv_buffer = (float *) mod_calloc(g_sample_rate, sizeof(float));
52625274
if (!cv_buffer)
52635275
{
5276+
pthread_mutex_unlock(&g_multi_thread_mutex);
52645277
fprintf(stderr, "can't get cv buffer\n");
52655278
error = ERR_MEMORY_ALLOCATION;
52665279
goto error;
@@ -5278,6 +5291,7 @@ int effects_add(const char *uri, int instance, int activate)
52785291
jack_port = jack_port_register(jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, jack_flags, 0);
52795292
if (jack_port == NULL)
52805293
{
5294+
pthread_mutex_unlock(&g_multi_thread_mutex);
52815295
fprintf(stderr, "can't get jack port\n");
52825296
error = ERR_JACK_PORT_REGISTER;
52835297
goto error;
@@ -5391,6 +5405,7 @@ int effects_add(const char *uri, int instance, int activate)
53915405
jack_port = jack_port_register(jack_client, port_name, JACK_DEFAULT_MIDI_TYPE, jack_flags, 0);
53925406
if (jack_port == NULL)
53935407
{
5408+
pthread_mutex_unlock(&g_multi_thread_mutex);
53945409
fprintf(stderr, "can't get jack port\n");
53955410
error = ERR_JACK_PORT_REGISTER;
53965411
goto error;
@@ -5661,8 +5676,12 @@ int effects_add(const char *uri, int instance, int activate)
56615676
}
56625677
}
56635678

5679+
pthread_mutex_unlock(&g_multi_thread_mutex);
5680+
56645681
AllocatePortBuffers(effect, control_in_size, control_out_size);
56655682

5683+
pthread_mutex_lock(&g_multi_thread_mutex);
5684+
56665685
{
56675686
// Index readable and writable properties
56685687
LilvNodes *writable_properties = lilv_world_find_nodes(
@@ -5703,6 +5722,10 @@ int effects_add(const char *uri, int instance, int activate)
57035722
lilv_nodes_free(readable_properties);
57045723
}
57055724

5725+
lilv_node_free(plugin_uri);
5726+
5727+
pthread_mutex_unlock(&g_multi_thread_mutex);
5728+
57065729
/* create ring buffer for events from socket/commandline */
57075730
if (control_in_size != 0)
57085731
{
@@ -5748,8 +5771,6 @@ int effects_add(const char *uri, int instance, int activate)
57485771

57495772
pthread_mutexattr_destroy(&mutex_atts);
57505773

5751-
lilv_node_free(plugin_uri);
5752-
57535774
/* Jack callbacks */
57545775
jack_set_thread_init_callback(jack_client, JackThreadInit, effect);
57555776
jack_set_process_callback(jack_client, ProcessPlugin, effect);
@@ -5796,7 +5817,10 @@ int effects_add(const char *uri, int instance, int activate)
57965817
return instance;
57975818

57985819
error:
5820+
pthread_mutex_lock(&g_multi_thread_mutex);
57995821
lilv_node_free(plugin_uri);
5822+
pthread_mutex_unlock(&g_multi_thread_mutex);
5823+
58005824
effects_remove(instance);
58015825
return error;
58025826
}
@@ -6193,9 +6217,9 @@ static void effects_remove_inner_loop(int effect_id)
61936217

61946218
pthread_mutex_lock(&g_hmi_mutex);
61956219
sys_serial_write(&g_hmi_data->server,
6196-
sys_serial_event_type_unassign,
6197-
effect->ports[i]->hmi_addressing->page,
6198-
effect->ports[i]->hmi_addressing->subpage, msg);
6220+
sys_serial_event_type_unassign,
6221+
effect->ports[i]->hmi_addressing->page,
6222+
effect->ports[i]->hmi_addressing->subpage, msg);
61996223
pthread_mutex_unlock(&g_hmi_mutex);
62006224
}
62016225

@@ -6205,7 +6229,11 @@ static void effects_remove_inner_loop(int effect_id)
62056229

62066230
// TODO destroy port mutexes
62076231
free(effect->ports[i]->buffer);
6232+
6233+
pthread_mutex_lock(&g_multi_thread_mutex);
62086234
lilv_scale_points_free(effect->ports[i]->scale_points);
6235+
pthread_mutex_unlock(&g_multi_thread_mutex);
6236+
62096237
free(effect->ports[i]);
62106238
}
62116239
}
@@ -6214,24 +6242,32 @@ static void effects_remove_inner_loop(int effect_id)
62146242

62156243
if (effect->properties)
62166244
{
6245+
pthread_mutex_lock(&g_multi_thread_mutex);
62176246
for (uint32_t i = 0; i < effect->properties_count; i++)
62186247
{
62196248
if (effect->properties[i])
62206249
{
62216250
lilv_node_free(effect->properties[i]->uri);
62226251
lilv_node_free(effect->properties[i]->type);
6223-
free(effect->properties[i]);
62246252
}
62256253
}
6254+
pthread_mutex_unlock(&g_multi_thread_mutex);
6255+
6256+
for (uint32_t i = 0; i < effect->properties_count; i++)
6257+
free(effect->properties[i]);
62266258
free(effect->properties);
62276259
}
62286260

62296261
if (effect->lilv_instance)
62306262
{
6263+
pthread_mutex_lock(&g_multi_thread_mutex);
6264+
62316265
if (effect->activated)
62326266
lilv_instance_deactivate(effect->lilv_instance);
62336267

62346268
lilv_instance_free(effect->lilv_instance);
6269+
6270+
pthread_mutex_unlock(&g_multi_thread_mutex);
62356271
}
62366272

62376273
if (effect->jack_client)
@@ -6262,11 +6298,13 @@ static void effects_remove_inner_loop(int effect_id)
62626298

62636299
if (effect->presets)
62646300
{
6301+
pthread_mutex_lock(&g_multi_thread_mutex);
62656302
for (uint32_t i = 0; i < effect->presets_count; i++)
6266-
{
62676303
lilv_free(effect->presets[i]->uri);
6304+
pthread_mutex_unlock(&g_multi_thread_mutex);
6305+
6306+
for (uint32_t i = 0; i < effect->presets_count; i++)
62686307
free(effect->presets[i]);
6269-
}
62706308
free(effect->presets);
62716309
}
62726310

@@ -6278,7 +6316,7 @@ static void effects_remove_inner_loop(int effect_id)
62786316
char state_filename[g_lv2_scratch_dir != NULL ? PATH_MAX : 1];
62796317
memset(state_filename, 0, sizeof(state_filename));
62806318
snprintf(state_filename, PATH_MAX-1, "%s/effect-%d",
6281-
g_lv2_scratch_dir, effect->instance);
6319+
g_lv2_scratch_dir, effect->instance);
62826320
RecursivelyRemovePluginPath(state_filename);
62836321
}
62846322

0 commit comments

Comments
 (0)