several bug fixes and minor feature changes:
[goodguy/history.git] / cinelerra-5.0 / guicast / bcsynchronous.C
index 4ea90a52b7a9e1f2265df376b765771deb46ab62..671ec0df036733fa9f1b5c1815bb893acca4d438 100644 (file)
@@ -72,97 +72,6 @@ PBufferID::PBufferID(int window_id, GLXPbuffer glx_pbuffer, GLXContext glx_conte
 
 
 
-BC_SynchGarbage::BC_SynchGarbage(BC_Synchronous *synchronous)
- : Thread(1, 0, 0)
-{
-       this->synchronous = synchronous;
-       more_garbage = new Condition(0, "BC_SynchGarbage::more_garbage", 0);
-       garbage_lock = new Mutex("BC_SyncGarbage::garbage_lock");
-       done = -1;
-}
-
-BC_SynchGarbage::~BC_SynchGarbage()
-{
-       if( running() ) {
-               quit();
-               join();
-       }
-       garbage.remove_all_objects();
-       delete more_garbage;
-       delete garbage_lock;
-}
-
-void BC_SynchGarbage::send_garbage(BC_SynchronousCommand *command)
-{
-       garbage_lock->lock("BC_SynchGarbage::send_garbage");
-       garbage.append(command);
-       garbage_lock->unlock();
-       more_garbage->unlock();
-}
-
-void BC_SynchGarbage::handle_garbage()
-{
-       garbage_lock->lock("BC_SynchGarbage::handle_garbage 0");
-       while( !done && garbage.total ) {
-               BC_SynchronousCommand *command = garbage.get(0);
-               garbage.remove_number(0);
-               garbage_lock->unlock();
-
-               switch(command->command) {
-               case BC_SynchronousCommand::QUIT:
-                       done = 1;
-                       break;
-
-               case BC_SynchronousCommand::DELETE_WINDOW:
-                       synchronous->delete_window_sync(command);
-                       break;
-
-               case BC_SynchronousCommand::DELETE_PIXMAP:
-                       synchronous->delete_pixmap_sync(command);
-                       break;
-
-               case BC_SynchronousCommand::DELETE_DISPLAY:
-                       synchronous->delete_display_sync(command);
-                       break;
-               }
-
-               delete command;
-               garbage_lock->lock("BC_SynchGarbage::handle_garbage 1");
-       }
-       garbage_lock->unlock();
-}
-
-
-void BC_SynchGarbage::start()
-{
-       done = 0;
-       Thread::start();
-}
-
-void BC_SynchGarbage::stop()
-{
-       if( running() ) {
-               quit();
-               join();
-       }
-}
-
-void BC_SynchGarbage::quit()
-{
-       BC_SynchronousCommand *command = new BC_SynchronousCommand();
-       command->command = BC_SynchronousCommand::QUIT;
-       send_garbage(command);
-}
-
-void BC_SynchGarbage::run()
-{
-       while( !done ) {
-               more_garbage->lock("BC_SynchGarbage::run");
-               handle_garbage();
-       }
-}
-
-
 BC_SynchronousCommand::BC_SynchronousCommand()
 {
        command = BC_SynchronousCommand::NONE;
@@ -197,12 +106,11 @@ BC_Synchronous::BC_Synchronous()
  : Thread(1, 0, 0)
 {
        lock_sync = new Mutex("BC_Synchronous::lock_sync");
-       sync_garbage = new BC_SynchGarbage(this);
-       next_command = new Condition(0, "BC_Synchronous::next_command", 0);
+       next_command = new Condition(0, "BC_Synchronous::next_command", 1);
        command_lock = new Mutex("BC_Synchronous::command_lock");
        table_lock = new Mutex("BC_Synchronous::table_lock");
        done = 0;
-       is_running = 0;
+       is_started = 0;
        current_window = 0;
        BC_WindowBase::get_resources()->set_synchronous(this);
 }
@@ -214,7 +122,6 @@ BC_Synchronous::~BC_Synchronous()
                join();
        }
        commands.remove_all_objects();
-       delete sync_garbage;
        delete lock_sync;
        delete next_command;
        delete command_lock;
@@ -226,23 +133,11 @@ void BC_Synchronous::sync_lock(const char *cp)
        lock_sync->lock(cp);
 }
 
-void BC_Synchronous::sync_lock(Display *display, const char *cp)
-{
-       // get both display lock and sync_lock
-       XLockDisplay(display);
-       while( lock_sync->trylock(cp) ) {
-               XUnlockDisplay(display);
-               usleep(100000);
-               XLockDisplay(display);
-       }
-}
-
 void BC_Synchronous::sync_unlock()
 {
        lock_sync->unlock();
 }
 
-void sync_unlock();
 BC_SynchronousCommand* BC_Synchronous::new_command()
 {
        return new BC_SynchronousCommand();
@@ -254,18 +149,22 @@ void BC_Synchronous::create_objects()
 
 void BC_Synchronous::start()
 {
-       sync_garbage->start();
-       run();
+       is_started = 1;
+       //run();
+       Thread::start();
 }
 
 void BC_Synchronous::quit()
 {
+       if( !is_started ) return;
+       is_started = 0;
        BC_SynchronousCommand *command = new_command();
        command->command = BC_SynchronousCommand::QUIT;
        command_lock->lock("BC_Synchronous::quit");
        commands.append(command);
        command_lock->unlock();
        next_command->unlock();
+       command->command_done->lock("BC_Synchronous::quit");
 }
 
 long BC_Synchronous::send_command(BC_SynchronousCommand *command)
@@ -287,9 +186,8 @@ long BC_Synchronous::send_command(BC_SynchronousCommand *command)
 
 void BC_Synchronous::run()
 {
-       is_running = 1;
+       sync_lock("BC_Synchronous::run 0");
        while(!done) {
-               next_command->lock("BC_Synchronous::run");
                command_lock->lock("BC_Synchronous::run");
                BC_SynchronousCommand *command = 0;
                if(commands.total) {
@@ -297,28 +195,43 @@ void BC_Synchronous::run()
                        commands.remove_number(0);
                }
                command_lock->unlock();
-               if( !command ) continue;
-
+               if( !command ) {
+                       sync_unlock();
+                       next_command->lock("BC_Synchronous::run");
+                       sync_lock("BC_Synchronous::run 1");
+                       continue;
+               }
 //printf("BC_Synchronous::run %d\n", command->command);
                handle_command_base(command);
        }
-       is_running = 0;
+       sync_unlock();
 }
 
 void BC_Synchronous::handle_command_base(BC_SynchronousCommand *command)
 {
-       sync_lock("BC_Synchronous::handle_command_base");
        switch(command->command) {
        case BC_SynchronousCommand::QUIT:
                done = 1;
                break;
 
+       case BC_SynchronousCommand::DELETE_WINDOW:
+               delete_window_sync(command);
+               break;
+
+       case BC_SynchronousCommand::DELETE_PIXMAP:
+               delete_pixmap_sync(command);
+               break;
+
+       case BC_SynchronousCommand::DELETE_DISPLAY:
+               delete_display_sync(command);
+               break;
+
        default:
                handle_command(command);
                break;
        }
+
        command->command_done->unlock();
-       sync_unlock();
 }
 
 void BC_Synchronous::handle_command(BC_SynchronousCommand *command)
@@ -449,9 +362,6 @@ void BC_Synchronous::dump_shader(unsigned int handle)
        if(!got_it) printf("BC_Synchronous::dump_shader couldn't find %d\n", handle);
 }
 
-// has to run in sync_garbage thread, because mwindow playback_3d
-// thread ends before all windows are deleted.  runs as synchronous
-// command since resources must be freed immediately
 void BC_Synchronous::delete_window(BC_WindowBase *window)
 {
 #ifdef HAVE_GL
@@ -476,7 +386,7 @@ void BC_Synchronous::delete_window_sync(BC_SynchronousCommand *command)
        Window win = command->win;
        GLXWindow glx_win = command->glx_win;
        GLXContext glx_context = command->glx_context;
-       sync_lock(display, "BC_Synchronous::delete_window_sync");
+       XLockDisplay(display);
 //int debug = 0;
 
 // texture ID's are unique to different contexts
@@ -529,7 +439,6 @@ void BC_Synchronous::delete_window_sync(BC_SynchronousCommand *command)
                glXDestroyContext(display, glx_context);
        command->command_done->unlock();
        XUnlockDisplay(display);
-       sync_unlock();
 #endif
 }
 
@@ -548,10 +457,9 @@ void BC_Synchronous::delete_display_sync(BC_SynchronousCommand *command)
 {
 #ifdef HAVE_GL
        Display *display = command->display;
-       sync_lock(display, "BC_Synchronous::delete_display_sync");
+       XLockDisplay(display);
        XUnlockDisplay(display);
        XCloseDisplay(display);
-       sync_unlock();
 #endif
 }
 
@@ -633,12 +541,11 @@ void BC_Synchronous::delete_pixmap_sync(BC_SynchronousCommand *command)
 #ifdef HAVE_GL
        Display *display = command->display;
        GLXWindow glx_win = command->glx_win;
-       sync_lock(display, "BC_Synchronous::delete_pixmap_sync");
+       XLockDisplay(display);
        glXMakeContextCurrent(display, glx_win, glx_win, command->glx_context);
        glXDestroyContext(display, command->glx_context);
        glXDestroyGLXPixmap(display, command->glx_pixmap);
        XUnlockDisplay(display);
-       sync_unlock();
 #endif
 }
 
@@ -646,7 +553,10 @@ void BC_Synchronous::delete_pixmap_sync(BC_SynchronousCommand *command)
 
 void BC_Synchronous::send_garbage(BC_SynchronousCommand *command)
 {
-       sync_garbage->send_garbage(command);
+       command_lock->lock("BC_Synchronous::send_garbage");
+       commands.append(command);
+       command_lock->unlock();
+       next_command->unlock();
 }
 
 BC_WindowBase* BC_Synchronous::get_window()