X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fguicast%2Fmutex.C;fp=cinelerra-5.1%2Fguicast%2Fmutex.C;h=a4a6e21f99f605c1e30fe7a7ffb6092cad5ab40b;hb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;hp=0000000000000000000000000000000000000000;hpb=52fcc46226f9df46f9ce9d0566dc568455a7db0b;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/guicast/mutex.C b/cinelerra-5.1/guicast/mutex.C new file mode 100644 index 00000000..a4a6e21f --- /dev/null +++ b/cinelerra-5.1/guicast/mutex.C @@ -0,0 +1,169 @@ + +/* + * CINELERRA + * Copyright (C) 2008 Adam Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include + +#ifndef NO_GUICAST +#include "bcsignals.h" +#endif +#include "mutex.h" + + +Mutex::Mutex(const char *title, int recursive) +{ + this->title = title; + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutex_init(&mutex, &attr); + pthread_mutex_init(&recursive_lock, &attr); + count = 0; + this->recursive = recursive; + thread_id = 0; + thread_id_valid = 0; +} + +Mutex::~Mutex() +{ + pthread_mutex_destroy(&mutex); + pthread_mutex_destroy(&recursive_lock); +#ifndef NO_GUICAST + UNSET_ALL_LOCKS(this); +#endif +} + +int Mutex::lock(const char *location) +{ +// Test recursive owner and give up if we already own it + if(recursive) + { + pthread_mutex_lock(&recursive_lock); + if(thread_id_valid && pthread_self() == thread_id) + { + count++; + pthread_mutex_unlock(&recursive_lock); + return 0; + } + pthread_mutex_unlock(&recursive_lock); + } + + +#ifndef NO_GUICAST + SET_LOCK(this, title, location); +#endif + if(pthread_mutex_lock(&mutex)) perror("Mutex::lock"); + + + +// Update recursive status for the first lock + if(recursive) + { + pthread_mutex_lock(&recursive_lock); + count = 1; + thread_id = pthread_self(); + thread_id_valid = 1; + pthread_mutex_unlock(&recursive_lock); + } + else + { + count = 1; + } + + +#ifndef NO_GUICAST + SET_LOCK2 +#endif + return 0; +} + +int Mutex::unlock() +{ +// Remove from recursive status + if(recursive) + { + pthread_mutex_lock(&recursive_lock); + count--; +// Still locked + if(count > 0) + { + pthread_mutex_unlock(&recursive_lock); + return 0; + } +// Not owned anymore + thread_id = 0; + thread_id_valid = 0; + pthread_mutex_unlock(&recursive_lock); + } + else + count = 0; + + +#ifndef NO_GUICAST + UNSET_LOCK(this); +#endif + + if(pthread_mutex_unlock(&mutex)) perror("Mutex::unlock"); + return 0; +} + +int Mutex::trylock(const char *location) +{ + if( count ) return EBUSY; + int ret = pthread_mutex_trylock(&mutex); + if( ret ) return ret; + +// Update recursive status for the first lock + if(recursive) { + pthread_mutex_lock(&recursive_lock); + count = 1; + thread_id = pthread_self(); + thread_id_valid = 1; + pthread_mutex_unlock(&recursive_lock); + } + else + count = 1; + +#ifndef NO_GUICAST + SET_LOCK(this, title, location); + SET_LOCK2 +#endif + return 0; +} + +int Mutex::is_locked() +{ + return count; +} + +int Mutex::reset() +{ + pthread_mutex_destroy(&mutex); + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutex_init(&mutex, &attr); + count = 0; + thread_id = 0; + thread_id_valid = 0; +#ifndef NO_GUICAST + UNSET_ALL_LOCKS(this) +#endif + return 0; +}