⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 thread.c,v

📁 版本控制CVS资源库转换成SVN库的转换程序
💻 C,V
📖 第 1 页 / 共 3 页
字号:
void thread_rwlock_unlock_c(rwlock_t *rwlock, int line, char *file){    pthread_rwlock_unlock(&rwlock->sys_rwlock);}void thread_exit_c(int val, int line, char *file){    thread_type *th = thread_self();#if defined(DEBUG_MUTEXES) && defined(CHECK_MUTEXES)    if (th) {        avl_node *node;        mutex_t *tmutex;        char name[40];        _mutex_lock(&_mutextree_mutex);        while (node) {            tmutex = (mutex_t *)node->key;            if (tmutex->thread_id == th->thread_id) {                LOG_WARN("Thread %d [%s] exiting in file %s line %d, without unlocking mutex [%s]",                      th->thread_id, th->name, file, line, mutex_to_string(tmutex, name));            }            node = avl_get_next (node);        }        _mutex_unlock(&_mutextree_mutex);    }#endif        if (th)    {#ifdef THREAD_DEBUG        LOG_INFO4("Removing thread %d [%s] started at [%s:%d], reason: 'Thread Exited'", th->thread_id, th->name, th->file, th->line);#endif        _mutex_lock(&_threadtree_mutex);        avl_delete(_threadtree, th, _free_thread_if_detached);        _mutex_unlock(&_threadtree_mutex);    }        pthread_exit((void *)val);}/* sleep for a number of microseconds */void thread_sleep(unsigned long len){#ifdef _WIN32    Sleep(len / 1000);#else# ifdef HAVE_NANOSLEEP    struct timespec time_sleep;    struct timespec time_remaining;    int ret;    time_sleep.tv_sec = len / 1000000;    time_sleep.tv_nsec = (len % 1000000) * 1000;    ret = nanosleep(&time_sleep, &time_remaining);    while (ret != 0 && errno == EINTR) {        time_sleep.tv_sec = time_remaining.tv_sec;        time_sleep.tv_nsec = time_remaining.tv_nsec;                ret = nanosleep(&time_sleep, &time_remaining);    }# else    struct timeval tv;    tv.tv_sec = len / 1000000;    tv.tv_usec = (len % 1000000);    select(0, NULL, NULL, NULL, &tv);# endif#endif}static void *_start_routine(void *arg){    thread_start_t *start = (thread_start_t *)arg;    void *(*start_routine)(void *) = start->start_routine;    void *real_arg = start->arg;    thread_type *thread = start->thread;    int detach = start->detached;    _block_signals();    free(start);    /* insert thread into thread tree here */    _mutex_lock(&_threadtree_mutex);    thread->sys_thread = pthread_self();    avl_insert(_threadtree, (void *)thread);    _mutex_unlock(&_threadtree_mutex);#ifdef THREAD_DEBUG    LOG_INFO4("Added thread %d [%s] started at [%s:%d]", thread->thread_id, thread->name, thread->file, thread->line);#endif    if (detach) {        pthread_detach(thread->sys_thread);        thread->detached = 1;    }    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);    /* call the real start_routine and start the thread    ** this should never exit!    */    (start_routine)(real_arg);#ifdef THREAD_DEBUG    LOG_WARN("Thread x should never exit from here!!!");#endif    return NULL;}thread_type *thread_self(void){    avl_node *node;    thread_type *th;    pthread_t sys_thread = pthread_self();    _mutex_lock(&_threadtree_mutex);    if (_threadtree == NULL) {#ifdef THREAD_DEBUG        LOG_WARN("Thread tree is empty, this must be wrong!");#endif        _mutex_unlock(&_threadtree_mutex);        return NULL;    }        node = avl_get_first(_threadtree);        while (node) {        th = (thread_type *)node->key;        if (th && pthread_equal(sys_thread, th->sys_thread)) {            _mutex_unlock(&_threadtree_mutex);            return th;        }                node = avl_get_next(node);    }    _mutex_unlock(&_threadtree_mutex);#ifdef THREAD_DEBUG    LOG_ERROR("Nonexistant thread alive...");#endif        return NULL;}void thread_rename(const char *name){    thread_type *th;    th = thread_self();    if (th->name) free(th->name);    th->name = strdup(name);}static void _mutex_lock(mutex_t *mutex) {    pthread_mutex_lock(&mutex->sys_mutex);}static void _mutex_unlock(mutex_t *mutex){    pthread_mutex_unlock(&mutex->sys_mutex);}void thread_library_lock(void){    _mutex_lock(&_library_mutex);}void thread_library_unlock(void){    _mutex_unlock(&_library_mutex);}void thread_join(thread_type *thread){    void *ret;    int i;    i = pthread_join(thread->sys_thread, &ret);    _mutex_lock(&_threadtree_mutex);    avl_delete(_threadtree, thread, _free_thread);    _mutex_unlock(&_threadtree_mutex);}/* AVL tree functions */#ifdef DEBUG_MUTEXESstatic int _compare_mutexes(void *compare_arg, void *a, void *b){    mutex_t *m1, *m2;    m1 = (mutex_t *)a;    m2 = (mutex_t *)b;    if (m1->mutex_id > m2->mutex_id)        return 1;    if (m1->mutex_id < m2->mutex_id)        return -1;    return 0;}#endifstatic int _compare_threads(void *compare_arg, void *a, void *b){    thread_type *t1, *t2;    t1 = (thread_type *)a;    t2 = (thread_type *)b;    if (t1->thread_id > t2->thread_id)        return 1;    if (t1->thread_id < t2->thread_id)        return -1;    return 0;}#ifdef DEBUG_MUTEXESstatic int _free_mutex(void *key){    mutex_t *m;    m = (mutex_t *)key;    if (m && m->file) {        free(m->file);        m->file = NULL;    }    /* all mutexes are static.  don't need to free them */    return 1;}#endifstatic int _free_thread(void *key){    thread_type *t;    t = (thread_type *)key;    if (t->file)        free(t->file);    if (t->name)        free(t->name);    free(t);    return 1;}static int _free_thread_if_detached(void *key){    thread_type *t = key;    if(t->detached)        return _free_thread(key);    return 1;}@1.24log@Brendan was getting pissed off about inconsistent indentation styles.Convert all tabs to 4 spaces. All code must now use 4 space indents.@text@d1 18a18 19/* threads.c** - Thread Abstraction Functions**** Copyright (c) 1999, 2000 the icecast team**** 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 latfer 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.*/@1.23log@avoid freeing a thread structure a second time.@text@d77 12a88 12	/* the real start routine and arg */	void *(*start_routine)(void *);	void *arg;	/* whether to create the threaded in detached state */	int detached;	/* the other stuff we need to make sure this thread is inserted into	** the thread tree	*/	thread_type *thread;	pthread_t sys_thread;d146 1a146 1	thread_type *thread;d148 1a148 1	/* set up logging */d151 3a153 3	log_initialize();	_logid = log_open("thread.log");	log_set_level(_logid, THREAD_DEBUG);d157 1a157 1	/* create all the internal mutexes, and initialize the mutex tree */d159 1a159 1	_mutextree = avl_tree_new(_compare_mutexes, NULL);d161 4a164 4	/* we have to create this one by hand, because there's no	** mutextree_mutex to lock yet! 	*/	_mutex_create(&_mutextree_mutex);d166 2a167 2	_mutextree_mutex.mutex_id = _next_mutex_id++;	avl_insert(_mutextree, (void *)&_mutextree_mutex);d170 2a171 2	thread_mutex_create(&_threadtree_mutex);	thread_mutex_create(&_library_mutex);	d173 1a173 1	/* initialize the thread tree and insert the main thread */d175 1a175 1	_threadtree = avl_tree_new(_compare_threads, NULL);d177 1a177 1	thread = (thread_type *)malloc(sizeof(thread_type));d179 6a184 6	thread->thread_id = _next_thread_id++;	thread->line = 0;	thread->file = strdup("main.c");	thread->sys_thread = pthread_self();	thread->create_time = time(NULL);	thread->name = strdup("Main Thread");d186 1a186 1	avl_insert(_threadtree, (void *)thread);d188 1a188 1	_catch_signals();d190 1a190 1	_initialized = 1;d195 3a197 3	if (_initialized == 1) {		thread_mutex_destroy(&_library_mutex);		thread_mutex_destroy(&_threadtree_mutex);d199 3a201 3		thread_mutex_destroy(&_mutextree_mutex);				avl_tree_free(_mutextree, _free_mutex);d203 2a204 2		avl_tree_free(_threadtree, _free_thread);	}d207 2a208 2	log_close(_logid);	log_shutdown();d271 8a278 12	int created;	thread_type *thread;	thread_start_t *start;	thread = (thread_type *)malloc(sizeof(thread_type));		start = (thread_start_t *)malloc(sizeof(thread_start_t));	thread->line = line;	thread->file = strdup(file);	_mutex_lock(&_threadtree_mutex);		thread->thread_id = _next_thread_id++;	_mutex_unlock(&_threadtree_mutex);d280 6a285 2	thread->name = strdup(name);	thread->create_time = time(NULL);d288 4a291 4	start->start_routine = start_routine;	start->arg = arg;	start->thread = thread;	start->detached = detached;d293 3a295 3	created = 0;	if (pthread_create(&thread->sys_thread, NULL, _start_routine, start) == 0)		created = 1;d297 2a298 2	else		LOG_ERROR("Could not create new thread");d301 1a301 1	if (created == 0) {d303 1a303 1		LOG_ERROR("System won't let me create more threads, giving up");d305 2a306 2		return NULL;	}d308 1a308 1	return thread;d318 2a319 2	mutex->thread_id = MUTEX_STATE_NEVERLOCKED;	mutex->line = -1;d322 1a322 1	pthread_mutex_init(&mutex->sys_mutex, NULL);d327 1a327 1	_mutex_create(mutex);d330 4a333 4	_mutex_lock(&_mutextree_mutex);	mutex->mutex_id = _next_mutex_id++;	avl_insert(_mutextree, (void *)mutex);	_mutex_unlock(&_mutextree_mutex);d339 1a339 1	pthread_mutex_destroy(&mutex->sys_mutex);d342 3a344 3	_mutex_lock(&_mutextree_mutex);	avl_delete(_mutextree, mutex, _free_mutex);	_mutex_unlock(&_mutextree_mutex);d351 1a351 1	thread_type *th = thread_self();d353 1a353 1	if (!th) LOG_WARN("No mt record for %u in lock [%s:%d]", thread_self(), file, line);d355 1a355 1	LOG_DEBUG5("Locking %p (%s) on line %d in file %s by thread %d", mutex, mutex->name, line, file, th ? th->thread_id : -1);d358 44a401 44	/* Just a little sanity checking to make sure that we're locking	** mutexes correctly	*/	if (th) {		int locks = 0;		avl_node *node;		mutex_t *tmutex;		_mutex_lock(&_mutextree_mutex);		node = avl_get_first (_mutextree);				while (node) {			tmutex = (mutex_t *)node->key;			if (tmutex->mutex_id == mutex->mutex_id) {				if (tmutex->thread_id == th->thread_id) { 					/* Deadlock, same thread can't lock the same mutex twice */					LOG_ERROR7("DEADLOCK AVOIDED (%d == %d) on mutex [%s] in file %s line %d by thread %d [%s]", 					     tmutex->thread_id, th->thread_id, mutex->name ? mutex->name : "undefined", file, line, th->thread_id, th->name);					_mutex_unlock(&_mutextree_mutex);					return;				}			} else if (tmutex->thread_id == th->thread_id) { 				/* Mutex locked by this thread (not this mutex) */				locks++;			}			node = avl_get_next(node);		}		if (locks > 0) { 			/* Has already got a mutex locked */			if (_multi_mutex.thread_id != th->thread_id) {				/* Tries to lock two mutexes, but has not got the double mutex, norty boy! */				LOG_WARN("(%d != %d) Thread %d [%s] tries to lock a second mutex [%s] in file %s line %d, without locking double mutex!",				     _multi_mutex.thread_id, th->thread_id, th->thread_id, th->name, mutex->name ? mutex->name : "undefined", file, line);			}		}				_mutex_unlock(&_mutextree_mutex);	}d403 10a412 10		_mutex_lock(mutex);		_mutex_lock(&_mutextree_mutex);	LOG_DEBUG2("Locked %p by thread %d", mutex, th ? th->thread_id : -1);	mutex->line = line;	if (th) {		mutex->thread_id = th->thread_id;	}d414 1a414 1	_mutex_unlock(&_mutextree_mutex);d416 1a416 1	_mutex_lock(mutex);d423 1a423 1	thread_type *th = thread_self();d425 3a427 3	if (!th) {		LOG_ERROR3("No record for %u in unlock [%s:%d]", thread_self(), file, line);	}d429 1a429 1	LOG_DEBUG5("Unlocking %p (%s) on line %d in file %s by thread %d", mutex, mutex->name, line, file, th ? th->thread_id : -1);d431 1a431 1	mutex->line = line;d434 20a453 30	if (th) {		int locks = 0;		avl_node *node;		mutex_t *tmutex;		_mutex_lock(&_mutextree_mutex);		while (node) {			tmutex = (mutex_t *)node->key;			if (tmutex->mutex_id == mutex->mutex_id) {				if (tmutex->thread_id != th->thread_id) {					LOG_ERROR7("ILLEGAL UNLOCK (%d != %d) on mutex [%s] in file %s line %d by thread %d [%s]", tmutex->thread_id, th->thread_id, 					     mutex->name ? mutex->name : "undefined", file, line, th->thread_id, th->name);					_mutex_unlock(&_mutextree_mutex);					return;				}			} else if (tmutex->thread_id == th->thread_id) {				locks++;			}			node = avl_get_next (node);		}		if ((locks > 0) && (_multi_mutex.thread_id != th->thread_id)) {			/* Don't have double mutex, has more than this mutex left */					LOG_WARN("(%d != %d) Thread %d [%s] tries to unlock a mutex [%s] in file %s line %d, without owning double mutex!",			     _multi_mutex.thread_id, th->thread_id, th->thread_id, th->name, mutex->name ? mutex->name : "undefined", file, line);		}d455 12a466 2		_mutex_unlock(&_mutextree_mutex);	}d469 1a469 1	_mutex_unlock(mutex);d471 1a471 1	_mutex_lock(&_mutextree_mutex);d473 5a477 5	LOG_DEBUG2("Unlocked %p by thread %d", mutex, th ? th->thread_id : -1);	mutex->line = -1;	if (mutex->thread_id == th->thread_id) {		mutex->thread_id = MUTEX_STATE_NOTLOCKED;	}d479 1a479 1	_mutex_unlock(&_mutextree_mutex);d481 1a481 1	_mutex_unlock(mutex);d487 2a488 2	pthread_cond_init(&cond->sys_cond, NULL);	pthread_mutex_init(&cond->cond_mutex, NULL);d493 2a494 2	pthread_mutex_destroy(&cond->cond_mutex);	pthread_cond_destroy(&cond->sys_cond);d499 1a499 1	pthread_cond_signal(&cond->sys_cond);d504 1a504 1	pthread_cond_broadcast(&cond->sys_cond);d521 3a523 3	pthread_mutex_lock(&cond->cond_mutex);	pthread_cond_wait(&cond->sys_cond, &cond->cond_mutex);	pthread_mutex_unlock(&cond->cond_mutex);d528 1a528 1	pthread_rwlock_init(&rwlock->sys_rwlock, NULL);d533 1a533 1	pthread_rwlock_destroy(&rwlock->sys_rwlock);d538 1a538 1	pthread_rwlock_rdlock(&rwlock->sys_rwlock);d543 1a543 1	pthread_rwlock_wrlock(&rwlock->sys_rwlock);d548 1a548 1	pthread_rwlock_unlock(&rwlock->sys_rwlock);d553 1a553 1	thread_type *th = thread_self();d556 14a569 4	if (th) {		avl_node *node;		mutex_t *tmutex;		char name[40];d571 2a572 4		_mutex_lock(&_mutextree_mutex);		while (node) {			tmutex = (mutex_t *)node->key;d574 2a575 10			if (tmutex->thread_id == th->thread_id) {				LOG_WARN("Thread %d [%s] exiting in file %s line %d, without unlocking mutex [%s]", 				     th->thread_id, th->name, file, line, mutex_to_string(tmutex, name));			}			node = avl_get_next (node);		}		_mutex_unlock(&_mutextree_mutex);	}d577 2a578 2		if (th)	{d580 1a580 1		LOG_INFO4("Removing thread %d [%s] started at [%s:%d], reason: 'Thread Exited'", th->thread_id, th->name, th->file, th->line);d583 6a588 6		_mutex_lock(&_threadtree_mutex);    	avl_delete(_threadtree, th, _free_thread_if_detached);		_mutex_unlock(&_threadtree_mutex);	}		pthread_exit((void *)val);d595 1a595 1

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -