pay some attention to the special guest of the night: KDE window stacking
[ardour.git] / gtk2_ardour / linux_vst_gui_support.cc
index c86fb946cc42c18ba6b2205173182a41112a76f3..b310227403bdceab2b724bd0015dba568c405076 100644 (file)
@@ -56,7 +56,7 @@ static VSTState * vstfx_first = NULL;
 
 const char magic[] = "VSTFX Plugin State v002";
 
-static int gui_quit = 0;
+static volatile int gui_quit = 0;
 
 /*This will be our connection to X*/
 
@@ -302,29 +302,6 @@ dispatch_x_events (XEvent* event, VSTState* vstfx)
        vstfx->eventProc((void*)event);
 }
 
-static void
-maybe_set_program (VSTState* vstfx)
-{
-       if (vstfx->want_program != -1) {
-               if (vstfx->vst_version >= 2) {
-                       vstfx->plugin->dispatcher (vstfx->plugin, 67 /* effBeginSetProgram */, 0, 0, NULL, 0);
-               }
-
-               vstfx->plugin->dispatcher (vstfx->plugin, effSetProgram, 0, vstfx->want_program, NULL, 0);
-
-               if (vstfx->vst_version >= 2) {
-                       vstfx->plugin->dispatcher (vstfx->plugin, 68 /* effEndSetProgram */, 0, 0, NULL, 0);
-               }
-
-               vstfx->want_program = -1;
-       }
-
-       if (vstfx->want_chunk == 1) {
-               vstfx->plugin->dispatcher (vstfx->plugin, 24 /* effSetChunk */, 1, vstfx->wanted_chunk_size, vstfx->wanted_chunk, 0);
-               vstfx->want_chunk = 0;
-       }
-}
-
 /** This is the main gui event loop for the plugin, we also need to pass
 any Xevents to all the UI callbacks plugins 'may' have registered on their
 windows, that is if they don't manage their own UIs **/
@@ -437,7 +414,7 @@ again:
                                        }
                                }
 
-                               maybe_set_program (vstfx);
+                               vststate_maybe_set_program (vstfx);
                                vstfx->want_program = -1;
                                vstfx->want_chunk = 0;
 
@@ -471,7 +448,7 @@ again:
                        clock1 = g_get_monotonic_time();
                }
 
-               if (may_sleep && elapsed_time_ms + 1 < LXVST_sched_timer_interval) {
+               if (!gui_quit && may_sleep && elapsed_time_ms + 1 < LXVST_sched_timer_interval) {
                        Glib::usleep(1000 * (LXVST_sched_timer_interval - elapsed_time_ms - 1));
                }
        }
@@ -487,6 +464,8 @@ normally started in globals.cc*/
 
 int vstfx_init (void* ptr)
 {
+       assert (gui_quit == 0);
+       pthread_mutex_init (&plugin_mutex, NULL);
 
        int thread_create_result;
 
@@ -553,7 +532,11 @@ void vstfx_exit()
        /*We need to pthread_join the gui_thread here so
        we know when it has stopped*/
 
+       // BEWARE: some Plugin GUIs can crash if the thread local storage is free()d
+       // after the shared library containing the destructor is already dl-closed.
+       // (e.g u-he LXVST GUI, crash in __nptl_deallocate_tsd) :(
        pthread_join(LXVST_gui_event_thread, NULL);
+       pthread_mutex_destroy (&plugin_mutex);
 }
 
 /*Adds a new plugin (VSTFX) instance to the linked list*/