Skip to content

Commit cd8fe41

Browse files
committed
Make multi add/remove/preload thread-safe
Signed-off-by: falkTX <[email protected]>
1 parent 864e926 commit cd8fe41

File tree

1 file changed

+52
-19
lines changed

1 file changed

+52
-19
lines changed

src/effects.c

Lines changed: 52 additions & 19 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,13 +5131,14 @@ 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;
51275138
}
51285139
port->jack_port = jack_port;
5129-
51305140
audio_ports_count++;
5141+
51315142
if (lilv_port_is_a(plugin, lilv_port, g_lilv_nodes.input)) input_audio_ports_count++;
51325143
else if (lilv_port_is_a(plugin, lilv_port, g_lilv_nodes.output)) output_audio_ports_count++;
51335144
}
@@ -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;
@@ -5185,7 +5197,6 @@ int effects_add(const char *uri, int instance, int activate)
51855197
/* Set the default value of control */
51865198
float def_value;
51875199

5188-
51895200
if (lilv_port_has_property(plugin, lilv_port, g_lilv_nodes.preferMomentaryOff))
51905201
{
51915202
def_value = max_value;
@@ -5261,14 +5272,12 @@ int effects_add(const char *uri, int instance, int activate)
52615272
cv_buffer = (float *) mod_calloc(g_sample_rate, sizeof(float));
52625273
if (!cv_buffer)
52635274
{
5275+
pthread_mutex_unlock(&g_multi_thread_mutex);
52645276
fprintf(stderr, "can't get cv buffer\n");
52655277
error = ERR_MEMORY_ALLOCATION;
52665278
goto error;
52675279
}
52685280

5269-
if (lilv_port_is_a(plugin, lilv_port, g_lilv_nodes.mod_cvport))
5270-
port->hints |= HINT_CV_MOD;
5271-
52725281
port->buffer = cv_buffer;
52735282
port->buffer_count = g_sample_rate;
52745283
lilv_instance_connect_port(lilv_instance, i, cv_buffer);
@@ -5278,11 +5287,15 @@ int effects_add(const char *uri, int instance, int activate)
52785287
jack_port = jack_port_register(jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, jack_flags, 0);
52795288
if (jack_port == NULL)
52805289
{
5290+
pthread_mutex_unlock(&g_multi_thread_mutex);
52815291
fprintf(stderr, "can't get jack port\n");
52825292
error = ERR_JACK_PORT_REGISTER;
52835293
goto error;
52845294
}
52855295

5296+
if (lilv_port_is_a(plugin, lilv_port, g_lilv_nodes.mod_cvport))
5297+
port->hints |= HINT_CV_MOD;
5298+
52865299
/* Set the minimum value of control */
52875300
float min_value;
52885301
LilvNodes* lilvvalue_minimum = lilv_port_get_value(plugin, lilv_port, g_lilv_nodes.mod_minimum);
@@ -5391,6 +5404,7 @@ int effects_add(const char *uri, int instance, int activate)
53915404
jack_port = jack_port_register(jack_client, port_name, JACK_DEFAULT_MIDI_TYPE, jack_flags, 0);
53925405
if (jack_port == NULL)
53935406
{
5407+
pthread_mutex_unlock(&g_multi_thread_mutex);
53945408
fprintf(stderr, "can't get jack port\n");
53955409
error = ERR_JACK_PORT_REGISTER;
53965410
goto error;
@@ -5411,9 +5425,13 @@ int effects_add(const char *uri, int instance, int activate)
54115425
portitemptr->instance = instance;
54125426
portitemptr->jack_port = jack_port;
54135427

5428+
pthread_mutex_unlock(&g_multi_thread_mutex);
54145429
pthread_mutex_lock(&g_raw_midi_port_mutex);
5430+
54155431
list_add_tail(&portitemptr->siblings, &g_raw_midi_port_list);
5432+
54165433
pthread_mutex_unlock(&g_raw_midi_port_mutex);
5434+
pthread_mutex_lock(&g_multi_thread_mutex);
54175435
}
54185436
}
54195437
}
@@ -5703,6 +5721,10 @@ int effects_add(const char *uri, int instance, int activate)
57035721
lilv_nodes_free(readable_properties);
57045722
}
57055723

5724+
lilv_node_free(plugin_uri);
5725+
5726+
pthread_mutex_unlock(&g_multi_thread_mutex);
5727+
57065728
/* create ring buffer for events from socket/commandline */
57075729
if (control_in_size != 0)
57085730
{
@@ -5748,8 +5770,6 @@ int effects_add(const char *uri, int instance, int activate)
57485770

57495771
pthread_mutexattr_destroy(&mutex_atts);
57505772

5751-
lilv_node_free(plugin_uri);
5752-
57535773
/* Jack callbacks */
57545774
jack_set_thread_init_callback(jack_client, JackThreadInit, effect);
57555775
jack_set_process_callback(jack_client, ProcessPlugin, effect);
@@ -5796,7 +5816,10 @@ int effects_add(const char *uri, int instance, int activate)
57965816
return instance;
57975817

57985818
error:
5819+
pthread_mutex_lock(&g_multi_thread_mutex);
57995820
lilv_node_free(plugin_uri);
5821+
pthread_mutex_unlock(&g_multi_thread_mutex);
5822+
58005823
effects_remove(instance);
58015824
return error;
58025825
}
@@ -6193,9 +6216,9 @@ static void effects_remove_inner_loop(int effect_id)
61936216

61946217
pthread_mutex_lock(&g_hmi_mutex);
61956218
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);
6219+
sys_serial_event_type_unassign,
6220+
effect->ports[i]->hmi_addressing->page,
6221+
effect->ports[i]->hmi_addressing->subpage, msg);
61996222
pthread_mutex_unlock(&g_hmi_mutex);
62006223
}
62016224

@@ -6205,7 +6228,11 @@ static void effects_remove_inner_loop(int effect_id)
62056228

62066229
// TODO destroy port mutexes
62076230
free(effect->ports[i]->buffer);
6231+
6232+
pthread_mutex_lock(&g_multi_thread_mutex);
62086233
lilv_scale_points_free(effect->ports[i]->scale_points);
6234+
pthread_mutex_unlock(&g_multi_thread_mutex);
6235+
62096236
free(effect->ports[i]);
62106237
}
62116238
}
@@ -6214,15 +6241,19 @@ static void effects_remove_inner_loop(int effect_id)
62146241

62156242
if (effect->properties)
62166243
{
6244+
pthread_mutex_lock(&g_multi_thread_mutex);
62176245
for (uint32_t i = 0; i < effect->properties_count; i++)
62186246
{
62196247
if (effect->properties[i])
62206248
{
62216249
lilv_node_free(effect->properties[i]->uri);
62226250
lilv_node_free(effect->properties[i]->type);
6223-
free(effect->properties[i]);
62246251
}
62256252
}
6253+
pthread_mutex_unlock(&g_multi_thread_mutex);
6254+
6255+
for (uint32_t i = 0; i < effect->properties_count; i++)
6256+
free(effect->properties[i]);
62266257
free(effect->properties);
62276258
}
62286259

@@ -6262,11 +6293,13 @@ static void effects_remove_inner_loop(int effect_id)
62626293

62636294
if (effect->presets)
62646295
{
6296+
pthread_mutex_lock(&g_multi_thread_mutex);
62656297
for (uint32_t i = 0; i < effect->presets_count; i++)
6266-
{
62676298
lilv_free(effect->presets[i]->uri);
6299+
pthread_mutex_unlock(&g_multi_thread_mutex);
6300+
6301+
for (uint32_t i = 0; i < effect->presets_count; i++)
62686302
free(effect->presets[i]);
6269-
}
62706303
free(effect->presets);
62716304
}
62726305

@@ -6278,7 +6311,7 @@ static void effects_remove_inner_loop(int effect_id)
62786311
char state_filename[g_lv2_scratch_dir != NULL ? PATH_MAX : 1];
62796312
memset(state_filename, 0, sizeof(state_filename));
62806313
snprintf(state_filename, PATH_MAX-1, "%s/effect-%d",
6281-
g_lv2_scratch_dir, effect->instance);
6314+
g_lv2_scratch_dir, effect->instance);
62826315
RecursivelyRemovePluginPath(state_filename);
62836316
}
62846317

0 commit comments

Comments
 (0)