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

📄 cancel.c

📁 rtai-3.1-test3的源代码(Real-Time Application Interface )
💻 C
字号:
/* * Written by Gilles Chanteperdrix <gilles.chanteperdrix@laposte.net>. * * 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 "pse51/thread.h"#include "pse51/cancel.h"typedef void (*cleanup_routine_t) (void *);typedef struct {    cleanup_routine_t routine;    void *arg;    xnholder_t link;#define link2cleanup_handler(laddr) \((cleanup_handler_t *)(((char *)laddr)-(int)(&((cleanup_handler_t *)0)->link)))} cleanup_handler_t;int pthread_cancel(pthread_t thread){    int cancel_enabled;        xnpod_check_context(XNPOD_THREAD_CONTEXT);    xnmutex_lock(&__imutex);    if (!pse51_obj_active(thread,PSE51_THREAD_MAGIC,struct pse51_thread)) {	xnmutex_unlock(&__imutex);	return ESRCH;    }    if( (cancel_enabled = thread_getcancelstate(thread)==PTHREAD_CANCEL_ENABLE)       && thread_getcanceltype(thread)==PTHREAD_CANCEL_ASYNCHRONOUS)        pse51_thread_abort(thread, PTHREAD_CANCELED, &__imutex);    else {        /* pthread_cancel is not a cancellation point, so           thread == pthread_self() is not a special case. */        thread_setcancel(thread);        if(cancel_enabled) {            /* Unblock thread, so that it can honor the cancellation request. */            xnpod_unblock_thread(&thread->threadbase);            xnpod_schedule(&__imutex);        }    }    xnmutex_unlock(&__imutex);    return 0;}void pthread_cleanup_push(cleanup_routine_t routine, void *arg){    cleanup_handler_t *handler;    if(!routine)        return;    xnpod_check_context(XNPOD_THREAD_CONTEXT);    /* The allocation is inside the critical section in order to make the       function async-signal safe, that is in order to avoid leaks if an       asynchronous cancellation request could occur between the call to       xnmalloc and xnmutex_lock. */    xnmutex_lock(&__imutex);    if(!(handler = xnmalloc(sizeof(*handler)))) {        xnmutex_unlock(&__imutex);        return ;    }    handler->routine=routine;    handler->arg=arg;    inith(&handler->link);    prependq(thread_cleanups(pse51_current_thread()), &handler->link);    xnmutex_unlock(&__imutex);}void pthread_cleanup_pop(int execute){    xnholder_t *holder;    cleanup_handler_t *handler;    xnpod_check_context(XNPOD_THREAD_CONTEXT);    xnmutex_lock(&__imutex);    if(!(holder=getq(thread_cleanups(pse51_current_thread())))) {        xnmutex_unlock(&__imutex);        return;    }    handler=link2cleanup_handler(holder);    if(execute)        handler->routine(handler->arg);    xnmutex_unlock(&__imutex);    xnfree(handler);}int pthread_setcanceltype(int type, int *oldtype_ptr){    int oldtype;    pthread_t cur;        xnpod_check_context(XNPOD_THREAD_CONTEXT);        switch(type) {    default:        return EINVAL;    case PTHREAD_CANCEL_DEFERRED:    case PTHREAD_CANCEL_ASYNCHRONOUS:        break;    }    cur = pse51_current_thread();        xnmutex_lock(&__imutex);    oldtype=thread_getcanceltype(cur);    thread_setcanceltype(cur, type);    if(type == PTHREAD_CANCEL_ASYNCHRONOUS       && thread_getcancelstate(cur) == PTHREAD_CANCEL_ENABLE)        thread_cancellation_point(cur, &__imutex);    if(oldtype_ptr)        *oldtype_ptr=oldtype;    xnmutex_unlock(&__imutex);    return 0;}int pthread_setcancelstate(int state, int *oldstate_ptr){    int oldstate;    pthread_t cur;        xnpod_check_context(XNPOD_THREAD_CONTEXT);        switch(state) {    default:        return EINVAL;    case PTHREAD_CANCEL_ENABLE:    case PTHREAD_CANCEL_DISABLE:        break;    }    cur = pse51_current_thread();    xnmutex_lock(&__imutex);    oldstate = thread_getcancelstate(cur);    thread_setcancelstate(cur, state);    if(state == PTHREAD_CANCEL_ENABLE       && thread_getcanceltype(cur) == PTHREAD_CANCEL_ASYNCHRONOUS)        thread_cancellation_point(cur, &__imutex);        if(oldstate_ptr)        *oldstate_ptr=oldstate;    xnmutex_unlock(&__imutex);    return 0;}void pthread_testcancel(void){    xnpod_check_context(XNPOD_THREAD_CONTEXT);    xnmutex_lock(&__imutex);    thread_cancellation_point(pse51_current_thread(), &__imutex);    xnmutex_lock(&__imutex);}void pse51_cancel_init_thread(pthread_t thread){    thread_setcancelstate(thread, PTHREAD_CANCEL_ENABLE);    thread_setcanceltype(thread, PTHREAD_CANCEL_DEFERRED);    thread_clrcancel(thread);    initq(thread_cleanups(thread));}void pse51_cancel_cleanup_thread(pthread_t thread){    xnholder_t *holder;    while((holder = getq(thread_cleanups(thread)))) {        cleanup_handler_t *handler = link2cleanup_handler(holder);        handler->routine(handler->arg);        xnfree(handler);    }}

⌨️ 快捷键说明

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