-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;
: 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);
}
join();
}
commands.remove_all_objects();
- delete sync_garbage;
delete lock_sync;
delete next_command;
delete command_lock;
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();
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)
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) {
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)
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
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
glXDestroyContext(display, glx_context);
command->command_done->unlock();
XUnlockDisplay(display);
- sync_unlock();
#endif
}
{
#ifdef HAVE_GL
Display *display = command->display;
- sync_lock(display, "BC_Synchronous::delete_display_sync");
+ XLockDisplay(display);
XUnlockDisplay(display);
XCloseDisplay(display);
- sync_unlock();
#endif
}
#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
}
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()